LoginSignup
1
1

More than 1 year has passed since last update.

Go言語豆知識(一)

Last updated at Posted at 2021-07-30

豆知識

Go言語には、スライスという概念があります。スライスは値型ではなく、参照型のデータです。スライスは値型のArrayを参照しています。
スライスを拡張するにはappendメソッドを使います。もしスライスを拡張するときに、元に参照するArrayの長さを超えた場合は、新しい参照元Arrayを再作りすることになります。

コード

    slice1 := []int{1,2,3,4}
    slice2 := slice1[:3]

    fmt.Println("最初の段階、slice1,slice2はおなじ参照元Arrayを参照しています")
    fmt.Println(slice1)
    fmt.Println(slice2)

    fmt.Println(&slice1[0])
    fmt.Println(&slice2[0])
    fmt.Println()

    fmt.Println("slice2の長さはまた参照元Arrayの長さを超えていない")
    slice2 = append(slice2, 15)

    fmt.Println(slice1)
    fmt.Println(slice2)

    fmt.Println(&slice1[0])
    fmt.Println(&slice2[0])
    fmt.Println()

    fmt.Print("slice2は元のArrayの長さを超えました。")
    slice2 = append(slice2, 16)
    fmt.Println(slice1)
    fmt.Println(slice2)

    fmt.Println(&slice1[0])
    fmt.Println(&slice2[0])

最初の段階、slice1,slice2はおなじ参照元Arrayを参照しています
[1 2 3 4]
[1 2 3]
0xc0000b4000 <-参照元のアドレス(Array)
0xc0000b4000 <-参照元のアドレス(Array)

slice2の長さはまた参照元Arrayの長さを超えていない
[1 2 3 15]
[1 2 3 15]
0xc0000b4000 <-参照元のアドレス(Array)
0xc0000b4000 <-参照元のアドレス(Array)

slice2は元のArrayの長さを超えました。[1 2 3 15]
[1 2 3 15 16]
0xc0000b4000 <-参照元のアドレスA(Array)
0xc0000b8000 <-参照元のアドレス(新しいArray)

出力のように、最初slice1とslice2はおなじ参照元長さが4のArrayに参照しています。
slice1はArrayの0-3番目まで切り出しています。
slice2はArrayの0-2番目まで切り出しています。

1回目のappend作業をしてら、slice2の長さは3から4までに伸ばしました。そのときに参照元Arrayの長さは4です。slice2の拡張によって、参照元Arrayの4番目値が修正されました。

2回目のappend作業をしてら、slice2の長さは4から5までに伸ばしました。そのときに参照元Arrayの長さは4です。
もともとの参照元Array(長さ4)はslice2(長さ5)を納めないから、slice2の参照を収めるために、新しい参照元を作ることになります。
そのときに、slice1の参照元とslice2の参照元はそれぞれ異なる参照元になります。

0xc0000b4000 <-参照元のアドレスA(Array)
0xc0000b8000 <-参照元のアドレス(新しいArray)

説明

名称未設定.001.jpeg

名称未設定.002.jpeg

名称未設定.003.jpeg

まとめ

スライスは参照しているArrayの長さを超えたら、新しい参照元を作成することになります。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1