メインコンテンツにスキップ
モジュール 4 · レッスン 2 / 5コース内の 17/50~15 min
モジュールのレッスン (2/5)

スライス: 慣用的な構造

スライス は Go で最もよく使用されるデータ構造です。動的 ビューです。 基礎となる配列に対して。構文: []T。配列とは異なり、長さは タイプの一部ではないため、append を使用して拡張できます。

スライスの解剖学

内部的には、スライスは 3 つのフィールド構造です。

  • 基礎となる配列の最初の要素への ポインター
  • length (len): 表示される要素の数
  • 容量 (cap): ビューの先頭から使用できる要素 基礎となる配列の最後まで
Go
s := []int{10, 20, 30}
fmt.Println(len(s), cap(s)) // 3 3

創造

Go
a := []int{1, 2, 3}          // literal
b := make([]int, 3)          // [0 0 0]   len=3 cap=3
c := make([]int, 3, 10)      // len=3 cap=10 (reserved)
var d []int                  // nil slice: len=0 cap=0, still usable with append

append: 常に結果を割り当てます

append は要素を追加し、新しいスライスを返します (潜在的に 容量が不十分な場合は新しいアレイを割り当てます):

Go
s := []int{1, 2, 3}
s = append(s, 4)              // [1 2 3 4]
s = append(s, 5, 6, 7)        // append multiple elements
s = append(s, altra...)       // concatenate another slice (spread)

スライス式 s[a:b]

a (これを含む) から b (これを除く) までのサブスライスを抽出します。

Go
s := []int{10, 20, 30, 40, 50}
sub := s[1:4]              // [20 30 40]
inizio := s[:2]            // [10 20]
fine := s[3:]              // [40 50]
intera := s[:]             // [10 20 30 40 50]

サブスライスは、元のスライスと 基礎となる配列を共有します。 sub[i] = ... による変更は s にも表示されます。

落とし穴: 配列の共有

Go
s := []int{1, 2, 3, 4}
sub := s[0:2]
sub[0] = 99
fmt.Println(s)             // [99 2 3 4] — modified!

独立したコピーを取得するには、copy または append を使用します。

Go
out := make([]int, len(sub))
copy(out, sub)

試してみてください

運動#go.m4.l2.e1
試行回数: 0読み込み中…

[1, 2, 3] でスライス s を作成し、append を使用して 4 を追加します。

エディターを読み込み中…
ヒントを表示

常に追加の結果を `s` に代入してください。

3 回の試行後に解決策が利用可能になります

運動#go.m4.l2.e2
試行回数: 0読み込み中…

スライス式を使用して、インデックス 1 を含むものから 3 を含まないもの (つまり、[20, 30]) から要素を抽出します。

エディターを読み込み中…
ヒントを表示

構文: `s[start:end]`、`start` を含み、`end` を除きます。

3 回の試行後に解決策が利用可能になります

Quiz#go.m4.l2.e3
準備完了

次のうち、書くのが間違っているのはどれですか?

Go
s := []int{1, 2, 3}
// (a) s = append(s, 4)
// (b) append(s, 4)
回答の選択肢

要約

  • []T: 配列の動的ビュー。トリプル (ptr、len、cap)。
  • make([]T, len, cap) を事前に割り当てます。 var s []T は使用可能な nil スライスです。
  • s = append(s, ...): 常に結果を割り当てます。
  • s[a:b] は、独立したコピーの基になる配列 copy(...) を共有します。
  • nil スライス = 読み取り/範囲指定/追加が可能です。 nilマップとはまったく異なります。