Posted at

Goのslice expressionについて

Goのslice expression(スライス式, スライシング)をちゃんと理解できてなかったので、反省を込めてメモ。

まず何の変哲もないスライス。

sli := []int{1, 2, 3, 4, 5}

スライスの添字は 0 から始まり、 要素数-1 までになる。このsliの場合、添字は0 ~ 4となる。

slice expressionは、配列や配列へのポインタやスライスから、別のスライスを作るときに使う記法のこと。(ちなみに文字列にも使えるが、結果は文字列になる点が少し違う)

https://golang.org/ref/spec#Slice_expressions

s2 := sli[0:5] // 1, 2, 3, 4, 5

こんな風に a[low : high] と書くことで別のスライスを切り出すことができる。


  • lowとhighはどちらも添字が基準で、 $low \leq i < high$ の範囲が切り取られる


  • sli[0:5] とは、 $0 \leq i < 5$ の範囲を抜き出すので、つまりは 添字0~4を抜き出す意味になる


  • sli[:3] のようにlowを省略すると0の意味になる。 $0 \leq i < 3$ と同じ。


  • sli[1:] のようにhighを省略するとlen(sli)の意味になる。この場合は $1 \leq i < 5$ と同じ


    • つまり、sli[:]sli[0:len(sli)] と同じ意味




slice expressionの性質


  • できあがる新sliceの要素数は、high - low

  • low == highな値を設定すると、空のsliceが返ってくる

  • $0 \leq low \leq high \leq len(a)$ を満たさないと駄目。lowとhighの大小関係も重要


    • 満たしてないとpanic


      • ということは、もし対象の要素数が未知数なら、あらかじめサイズの確認は必須





  • pythonなど、他言語にあるような超高機能なslice式ではない


    • 負の値を指定してお尻から切り出す〜みたいな機能はない


      • len()を使え、ってことかな?



    • ステップを指定したりreverseを作る機能もない


      • そういうのはライブラリを使うのがgo文化ですね






なんでhighは一個大きな数字にしてるんだろう?

たぶん色々なロジックを書くときにわざわざ-1をせずに済み、便利だからでしょう。

配列の添字が1始まりじゃなくて0始まりになってるのと同じ理由だと思う。


full slice expressionについて

使ったことがないです。使いみちがよくわからない…

capをあえて広げて切り取れるという構文がある。

numbers := [10]int{0,1,2,3,4,5,6,7,8,9}

s := numbers[2:4:6]
fmt.Println(s) // [2, 3]
fmt.Println(cap(s)) // 4


参考文献

https://medium.com/golangspec/slice-expressions-in-go-963368c20765