ホームページ > バックエンド開発 > Golang > Go スライスを再スライスしても容量が必ずしも削減されないのはなぜですか?

Go スライスを再スライスしても容量が必ずしも削減されないのはなぜですか?

Barbara Streisand
リリース: 2024-12-17 02:21:24
オリジナル
753 人が閲覧しました

Why Does Re-slicing a Go Slice Not Always Reduce Its Capacity?

Golang でのスライスの再スライス

Go では、スライスにより要素のコレクションを管理する柔軟な方法が提供されます。スライスの作成とアクセスは簡単ですが、再スライスの動作を理解するのは難しい場合があります。この概念を説明するコード スニペットを見てみましょう。

package main

import "fmt"

func main() {
    a := make([]int, 5)
    printSlice("a", a)
    b := make([]int, 0, 5)
    printSlice("b", b)
    c := b[:2]
    printSlice("c", c)
    d := c[2:5]
    printSlice("d", d)
}

func printSlice(s string, x []int) {
    fmt.Printf("%s len=%d cap=%d %v\n",
        s, len(x), cap(x), x)
}
ログイン後にコピー

このコードは、長さ 5、容量 5 のスライス a を作成し、続いて長さと容量 0 と容量の 2 つのスライス b と c を作成します。それぞれ2。次に、スライス d が、開始インデックス 2 と終了インデックス 5 を持つ c の再スライスとして作成されます。

出力を観察すると、混乱を招く部分が生じます。

a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0] //why the capacity of c not 2 but 5 instead
d len=3 cap=3 [0 0 0]
ログイン後にコピー

再スライスについて理解する

スライスを再スライスするときは、次のことに留意することが重要です。スライスは、その基礎となる配列のコピーではありません。代わりに、これらは配列の一部を参照する ウィンドウ です。

  • スライス c の場合、スライス b の最初の 2 つの要素のスライスとして作成されます。 b の容量は 5 であるため、スライス c を拡張して残りの 3 つの要素を含めることができます。これが、その容量が 5 のままである理由です。
  • スライス d は、開始インデックス 2 を持つ c の再スライスとして作成されます。これは、d が [2, 5)。この範囲には 3 つの要素しか残っていないため、d の長さは 3 で、その容量は 3 です (合計容量が 5 の大きなスライスの一部であるため)。

さらなる説明

次のコードは、再スライス間の密接な関係を示しています。スライス:

func main() {
    b := make([]int, 0, 5)
    c := b[:2]
    d := c[1:5] // this is equivalent to d := b[1:5]
    d[0] = 1
    printSlice("c", c)
    printSlice("d", d)
}
ログイン後にコピー

出力:

c len=2 cap=5 [0 1] // modifying d has modified c
d len=4 cap=4 [1 0 0 0] 
ログイン後にコピー

これは、スライス d の要素を変更するとスライス c の要素に直接影響を与え、両方のスライスが共有していることを確認します。同じ基礎となるデータ。

以上がGo スライスを再スライスしても容量が必ずしも削減されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート