Go ツアーの「スライス ザ スライス」セクションでは、一見不可解な変化が発生します。最初の 2 つの値を削除してスライスを変更すると、その容量は 6 から 4 に変わります。この動作は、容量が一定のままであるべきであるという最初の仮定に矛盾します。この変更の背後にある理由をさらに詳しく見てみましょう。
スライス容量について
Go のスライスは、配列の抽象化を提供するデータ構造です。これらは基になる配列の要素を参照しますが、バッキング ストレージを所有しません。一方、容量は、スライス要素を保持できる基になる配列のサイズを表します。
容量削減の原因
要素を先頭から削除するスライスは、スライス データ ポインタを基になる配列内で右に移動します。その結果、スライスの現在のデータ ポインタと配列の終端の間の距離が減少します。この減少は、容量の減少として現れます。
最後の変更のみが容量に影響する理由
スライスの長さをゼロにするスライスや拡張などの他の操作スライスデータポインタを変更しないでください。変更するのはスライスの長さだけであり、データ ポインターと配列の終わりの間の距離には影響しません。したがって、容量は変更されません。
内部スライスの詳細
より深く理解するために、リフレクションを使用してスライス ヘッダーを出力できます:
<code class="go">func printSlice(s []int) { sh := (*reflect.SliceHeader)(unsafe.Pointer(&s)) fmt.Printf("header=%+v len=%d cap=%d %v\n", sh, len(s), cap(s), s) }</code>
次の出力は、変更の実行に伴うスライス ヘッダーの変更を示しています。
<code class="text">header=&{Data:272990208 Len:6 Cap:6} len=6 cap=6 [2 3 5 7 11 13] header=&{Data:272990208 Len:0 Cap:6} len=0 cap=6 [] header=&{Data:272990208 Len:4 Cap:6} len=4 cap=6 [2 3 5 7] header=&{Data:272990216 Len:2 Cap:4} len=2 cap=4 [5 7]</code>
ご覧のとおり、最後の変更によりデータ ポインターがシフトされ、その結果、容量が減少します。
概要
スライスの先頭から要素が削除されると、スライスの容量が変化する可能性があります。これは、スライス データ ポインタと基礎となる配列の終端との間の距離が短くなるからです。長さをゼロにスライスしたり、長さを拡張したりするなど、他のスライス操作は容量に影響しません。 Go スライスを効果的に操作するには、これらの概念を理解することが重要です。
以上がスライスの先頭で要素を削除すると容量が減少するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。