Goでは、組み込み関数append、len、およびcapはスライス(slices)を操作する際に重要な役割を果たします。
例:
arr := []int{1,2,3} arr2 := append(arr, 4) // arr2はcap(arr)に依存して、同じまたは新しいバックアレイになる可能性があります。
注意点:
スライスから「切り取った」部分に要素を追加してappendした場合、元の配列に影響を与えますか?
回答:capが許可する場合、appendは元の配列の「尾」に要素を追加し、元の配列を指すすべてのスライスで変更が見えます。
例:
a := []int{1,2,3,4} b := a[:2] // [1 2], len=2, cap=4 b = append(b, 10) // aが変更される: a -> [1, 2, 10, 4]
逸話
チームが子スライスに要素を追加したところ、親配列のデータが予期せず変更され、ビジネスロジックの不整合が生じ、ユーザー間のタスク配分においてデバッグが難しいバグを引き起こしました。
逸話
大きなスライスに対してappendを再度呼び出す際、常に新しい配列が再割り当てされると期待していましたが、実際にはシステムのいくつかの部分が同じ「バックアレイ」で動作し続け、レースコンディションやデータの損傷を引き起こしていました。
逸話
開発者はmakeを使って固定サイズのスライスを割り当てましたが、誤って引数を入れ替えました:make([]int, cap, len)。その結果、容量に基づくロジックが不意に長さに対して動作し、s[0:len]の範囲を超えるとパニックを引き起こしました。