質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

2回答

223閲覧

Goのスライスの結果が理解できない。

Airi.

総合スコア8

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

1グッド

0クリップ

投稿2024/04/10 14:09

内容

以下【コード】を実行したさい、
(4) s = s[1:4] の結果が [7 11 13] になるのかがわかりません。
有識者の方、教え頂けますと幸いです。

【コード】

package main import "fmt" func main() { // (1) s := []int{2, 3, 5, 7, 11, 13} printSlice(s) // (1)出力 => len=6 cap=6 [2 3 5 7 11 13] // (2) s = s[2:6] printSlice(s) // (2)出力 => len=4 cap=4 [5 7 11 13] // (1)の index 2 ~ index 5までスライス 【理解】 // (3) s = s[:0] printSlice(s) // (3)出力 => len=0 cap=4 [] // (1)(もしくは(2)??)の 〜index0までスライス 【理解】 // (4) s = s[1:4] printSlice(s) // (4)出力 => len=2 cap=2 [11 13] 【???】 // index 1 ~ index 3 までスライス // (3) の[]からスライスするのではなく、 // (1) の[2 3 5 7 11 13] からスライスするのでもなく、 // (2) の[5 7 11 13]からスライスされてる??? // (5) s = s[1:2] printSlice(s) // (5)出力 => len=1 cap=2 [11] } func printSlice(s []int) { fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) }

【出力結果】

len=6 cap=6 [2 3 5 7 11 13] len=4 cap=4 [5 7 11 13] len=0 cap=4 [] len=3 cap=3 [7 11 13] len=1 cap=2 [11]
ikedas👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

(3) 時点で s[5 7 11 13] のスライスの長さは0になりますが、容量はそのままです。なので [5 7 11 13] という情報はそのまま残っています。
スライスの左辺が0、または省略時にこの様な挙動になります。
上記を元に再度切り出しを行っているので、 (4) では4要素(len=0)のスライスから index 1 ~ index 3 を切り取っています。

情報を残したくない場合は [x:y:z][:y:z] といった完全スライス式を使います。

go

1// (3) 2s = s[:0:0]

投稿2024/04/10 17:17

Eggpan

総合スコア2743

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

以下のドキュメントで説明されていますが、slice の実体は構造体で、実際のデータ(array)へのポインタを保持しています。

Go Slices: usage and internals - The Go Programming Language

Slice internals

A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).
:
Slicing does not copy the slice's data. It creates a new slice value that points to the original array. This makes slice operations as efficient as manipulating array indices. Therefore, modifying the elements (not the slice itself) of a re-slice modifies the elements of the original slice

(3) の s = s[:0] を実行した後で、インデックスではなく slicing によって (2) の時点での slice データを参照することができます。

golang

1// (2) 2fmt.Printf("%p %p %p %p %p %p %p\n", s, &s[0], &s[1], &s[2], &s[3], &s[4], &s[5]) 3s = s[2:6] 4fmt.Printf("%p %p %p %p %p\n", s, &s[0], &s[1], &s[2], &s[3]) 5printSlice(s) // (2)出力 => len=4 cap=4 [5 7 11 13] 6// (1)の index 2 ~ index 5までスライス 7 8// (3) 9fmt.Printf("%p\n", s) 10s = s[:0] 11// fmt.Printf("%d\n", s[0]) // panic: runtime error: index out of range [0] with length 0 12fmt.Printf("%p %p %p %p %p\n", s, s[0:1], s[1:2], s[2:3], s[3:4]) 13fmt.Printf("%d %d %d %d %d\n", s, s[0:1], s[1:2], s[2:3], s[3:4]) 14printSlice(s) // (3)出力 => len=0 cap=4 [] 15// (2) の 〜index0までスライス(empty slice) 16 17// (4) 18fmt.Printf("%p %p %p\n", s[1:2], s[2:3], s[3:4]) 19s = s[1:4] 20fmt.Printf("%p %p %p\n", &s[0], &s[1], &s[2]) 21printSlice(s) // (4)出力 => len=3 cap=3 [7 11 13] 22// index 1 ~ index 3 までスライス 23// (3) の[]からスライスするのではなく、 24// (1) の[2 3 5 7 11 13] からスライスするのでもなく、 25// (2) の[5 7 11 13]からスライスされる 26 27// (2) 28// 0xc00001c120 0xc00001c120 0xc00001c128 0xc00001c130 0xc00001c138 0xc00001c140 0xc00001c148 29// 0xc00001c130 0xc00001c130 0xc00001c138 0xc00001c140 0xc00001c148 30// len=4 cap=4 [5 7 11 13] 31// (3) 32// 0xc00001c130 33// 0xc00001c130 0xc00001c130 0xc00001c138 0xc00001c140 0xc00001c148 34// [] [5] [7] [11] [13] 35// len=0 cap=4 [] 36// (4) 37// 0xc00001c138 0xc00001c140 0xc00001c148 38// 0xc00001c138 0xc00001c140 0xc00001c148 39// len=3 cap=3 [7 11 13]

投稿2024/04/10 17:54

melian

総合スコア19825

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問