GoのSliceこえー(いまさら)

2020/12/26 18:20

※ 商品のリンクをクリックして何かを購入すると私に少額の報酬が入ることがあります【広告表示】

Goはいい加減に少し触った程度なので順を追って見ている。

Sliceの挙動怖い

  package main

  import "fmt"

  func main() {
      ar1 := []int{1, 2, 3, 4, 5}
      sl1 := ar1[:4:4]
      sl1 = append(sl1, 1)
      fmt.Println("ar1:", ar1) // ar1: [1 2 3 4 5]
      fmt.Println("sl1:", sl1) // sl1: [1 2 3 4 1]

      ar2 := []int{1, 2, 3, 4, 5}
      sl2 := ar2[:4:4+1]
      sl2 = append(sl2, 1)
      fmt.Println("ar2:", ar2) // ar2: [1 2 3 4 1]
      fmt.Println("sl2:", sl2) // sl2: [1 2 3 4 1]
  }

sliceは元の配列への参照を持っているのだけれど、appendしたときにsliceの容量を超えた場合には、

つまり、sl1はsliceするときに頭から4つ分の要素をもった同容量のSliceを作っている。sl1に1をappendするときに元の配列への参照は切れているのでar1に影響は無い。

一方、sl2はsliceするときに容量を要素数+1にしている。appendしても容量不足にならないので5要素目に1をappendしてしまい、元のar2の5番目の要素が変更されている。

当たり前と言えば当たり前なのだけれど、Sliceちょいとこわい。今更間満載だけれど、メモ。

go: 1.15

Prev Entry

Next Entry