📑

Golang クイズ

2023/01/01に公開

クイズ
以下の書き型Aと書き型Bどっちでもスライスの反転しています
なぜA書き型だと、スライスだけ渡して、main関数のarr0が反転されますか?
なぜB書き型だと、main関数のarr0が反転されるため、スライスのポインタで渡す必要がありますか?

書き方A


func main() {
	arr0 := []int{
		1,2,3,4,5,
	}

	reverse(arr0)

	fmt.Println(arr0)
}

func reverse(arr []int) {
    l := 0
    r := len(arr) - 1

    for l < r {
        arr[l],arr[r] = arr[r],arr[l]

        l += 1
        r -= 1
    }
}

書き方B


func main() {
	arr0 := []int{
		1,2,3,4,5,
	}

	reverse(arr0)

	fmt.Println(arr0)
}

func reverse(arr *[]int) {
	tmp := make([]int, 0)
	n := len(*arr)
	for i:=n-1;i>=0;i-- {
		tmp = append(tmp, (*arr)[i])
	}
	*arr = tmp
}

まとめ

スライスは配列の参照なので、A案だと、reverse関数はunderlying配列のメモリを保持でてきます。
B案だと、新しいunderlying配列を用意しましたので、外のarr0を新しく作ったunderlyingに参考させるため、スライスのポインタを使う必要になります。

Discussion