サーチ…
前書き
スライスは、プログラマがメモリ管理を心配することなく必要な数の要素を追加できるように、配列をカプセル化するデータ構造です。結果のスライスはすべて同じ内部配列を指しているため、スライスを非常に効率的にサブスライスに分割できます。プログラマは多くの場合、他の多くのプログラミング言語で行われる配列のコピーを避けるために、これを利用することがよくあります。
構文
- slice:= make([] type、len、cap)//新しいスライスを作成する
- slice = append(slice、item)//スライスに項目を追加する
- slice = append(slice、items ...)//スライスにアイテムのスライスを追加する
- len:= len(slice)//スライスの長さを取得する
- cap:= cap(slice)//スライスの容量を取得する
- elNum:= copy(dst、slice)//スライスの内容を他のスライスにコピーする
スライスに追加する
slice = append(slice, "hello", "world")
2つのスライスを一緒に追加する
slice1 := []string{"!"}
slice2 := []string{"Hello", "world"}
slice := append(slice1, slice2...)
要素の削除/スライススライス
スライスから1つ以上の要素を削除する必要がある場合、または既存のスライスのサブスライスを操作する必要がある場合は、次の方法を使用できます。
次の例では、slice of intを使用していますが、これはすべてのタイプのスライスで機能します。
そのためには、スライスが必要です。魔法使いからいくつかの要素を削除します:
slice := []int{1, 2, 3, 4, 5, 6}
// > [1 2 3 4 5 6]
削除する要素のインデックスも必要です。
// index of first element to remove (corresponding to the '3' in the slice)
var first = 2
// index of last element to remove (corresponding to the '5' in the slice)
var last = 4
スライスをスライスして不要な要素を取り除くことができます:
// keeping elements from start to 'first element to remove' (not keeping first to remove),
// removing elements from 'first element to remove' to 'last element to remove'
// and keeping all others elements to the end of the slice
newSlice1 := append(slice[:first], slice[last+1:]...)
// > [1 2 6]
// you can do using directly numbers instead of variables
newSlice2 := append(slice[:2], slice[5:]...)
// > [1 2 6]
// Another way to do the same
newSlice3 := slice[:first + copy(slice[first:], slice[last+1:])]
// > [1 2 6]
// same that newSlice3 with hard coded indexes (without use of variables)
newSlice4 := slice[:2 + copy(slice[2:], slice[5:])]
// > [1 2 6]
1つの要素だけを削除するには、削除する最後のインデックスとして、この要素のインデックスを最初のANDとして配置する必要があります。
var indexToRemove = 3
newSlice5 := append(slice[:indexToRemove], slice[indexToRemove+1:]...)
// > [1 2 3 5 6]
// hard-coded version:
newSlice5 := append(slice[:3], slice[4:]...)
// > [1 2 3 5 6]
また、スライスの先頭から要素を削除することもできます。
newSlice6 := append(slice[:0], slice[last+1:]...)
// > [6]
// That can be simplified into
newSlice6 := slice[last+1:]
// > [6]
また、スライスの最後からいくつかの要素を削除することもできます:
newSlice7 := append(slice[:first], slice[first+1:len(slice)-1]...)
// > [1 2]
// That can be simplified into
newSlice7 := slice[:first]
// > [1 2]
新しいスライスに最初のものとまったく同じ要素が含まれている必要がある場合は、同じことを使用できますが、
last := first-1
使用できます。
(これは、事前にインデックスが計算されている場合に便利です)
長さと容量
スライスは長さと容量の両方を持っています。スライスの長さは現在スライス内にある要素の数ですが、容量はスライスが再配置する必要がある前に保持できる要素の数です。
組み込みのmake()
関数を使用してスライスを作成する場合は、その長さ、およびオプションでその容量を指定できます。容量が明示的に指定されていない場合は、指定された長さになります。
var s = make([]int, 3, 5) // length 3, capacity 5
組み込みのlen()
関数を使ってスライスの長さを確認することができます:
var n = len(s) // n == 3
組み込みのcap()
関数を使用して容量を確認することができます:
var c = cap(s) // c == 5
make()
によって作成された要素は、スライスの要素型のゼロ値に設定されます。
for idx, val := range s {
fmt.Println(idx, val)
}
// output:
// 0 0
// 1 0
// 2 0
インデックスが容量内であっても、スライスの長さを超えて要素にアクセスすることはできません。
var x = s[3] // panic: runtime error: index out of range
ただし、容量が長さを超えていれば、再割り当てせずに新しい要素を追加できます。
var t = []int{3, 4}
s = append(s, t) // s is now []int{0, 0, 0, 3, 4}
n = len(s) // n == 5
c = cap(s) // c == 5
新しい要素を受け入れる能力がないスライスに追加すると、基本となる配列が十分な容量で再割り当てされます。
var u = []int{5, 6}
s = append(s, u) // s is now []int{0, 0, 0, 3, 4, 5, 6}
n = len(s) // n == 7
c = cap(s) // c > 5
したがって、不必要な再割り当てを避けるために、必要なスペースを知っていれば、最初にスライスを作成するときに十分な容量を割り当てるのが一般的には良い方法です。
あるスライスから別のスライスへのコンテンツのコピー
スライスの内容を最初に空のスライスにコピーしたい場合、それを達成するために以下の手順を実行できます。
- ソーススライスを作成します。
var sourceSlice []interface{} = []interface{}{"Hello",5.10,"World",true}
- 次のようにして、ターゲットスライスを作成します。
- 長さ= sourceSliceの長さ
var destinationSlice []interface{} = make([]interface{},len(sourceSlice))
- コピー先のスライスの基になる配列がソーススライスのすべての要素を収容できるだけの大きさになったので、組み込み
copy
を使用して要素をコピーすることができcopy
。
copy(destinationSlice,sourceSlice)
スライスの作成
スライスは、プログラマがデータのリストを格納する典型的な方法です。
スライス変数を宣言するには、 []Type
構文を使用します。
var a []int
スライス変数を宣言して1行に初期化するには、 []Type{values}
構文を使用します。
var a []int = []int{3, 1, 4, 1, 5, 9}
スライスを初期化する別の方法は、 make
関数です。 3つの引数:スライス(またはマップ )のType
、 length
、およびcapacity
。
a := make([]int, 0, 5)
append
を使用して新しいスライスに要素を追加できappend
。
a = append(a, 5)
len
を使用してスライス内の要素の数を確認します。
length := len(a)
cap
を使ってスライスの容量を確認してください。容量は、スライスのメモリに現在割り当てられている要素の数です。いつでもGoは自動的により大きなスライスを作成するので、容量のあるスライスに追加することができます。
capacity := cap(a)
一般的なインデックス構文を使用して、スライス内の要素にアクセスできます。
a[0] // Gets the first member of `a`
range
付きのfor
ループを使用することもできrange
。最初の変数は指定された配列のインデックスで、2番目の変数はインデックスの値です。
for index, value := range a {
fmt.Println("Index: " + index + " Value: " + value) // Prints "Index: 0 Value: 5" (and continues until end of slice)
}
スライスのフィルタリング
新しい基本配列を割り当てずにスライスをフィルタリングするには:
// Our base slice
slice := []int{ 1, 2, 3, 4 }
// Create a zero-length slice with the same underlying array
tmp := slice[:0]
for _, v := range slice {
if v % 2 == 0 {
// Append desired values to slice
tmp = append(tmp, v)
}
}
// (Optional) Reassign the slice
slice = tmp // [2, 4]
スライスのゼロ値
sliceのゼロ値はnil
で、長さと容量は0
です。 nil
スライスには配列がありません。しかし、 []int{}
やmake([]int, 5)[5:]
ように長さと容量が0
でないスライスもあります。
nil値を持つ型はnil
sliceに変換できます:
s = []int(nil)
スライスが空であるかどうかをテストするには、次のようにします。
if len(s) == 0 {
fmt.Ptintf("s is empty.")
}