モジュール 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 appendappend: 常に結果を割り当てます
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マップとはまったく異なります。