2023-06-05
こんにちは。Goの話です。
Goのスライスでは map や filter といった関数型チックな書き方ができません。そのためコード量が多くなってしまい悶々としていたのですが、Go1.18で golang.org/x/exp/slices が用意されました。スライスを楽に扱えます。
今回は、そのソースコードを見ていきます。具体的には slices.Contains() という関数を取り上げます。
slices.Contains()
slices.Contains() は、要素の存在チェックをします。例えば次のように書きます。
import ( "golang.org/x/exp/slices" ) func main() { list := []string{"orange", "apple", "blueberry"} if slices.Contains(list, "orange") { // 存在する } }
slices.Contains() のソースコードを見る
ソースコードはこちらです。
func Contains[E comparable](s []E, v E) bool { return Index(s, v) >= 0 }
まず入出力ですが、ジェネリクスができます。型制約は comparable です。雑に言うと「比較できるもの」でしょうか。例えばstringやintが該当します。他にも沢山あるので詳しくはドキュメントをご覧ください。
さて、処理としては slices.Index() を呼んでます。
slices.Index() のソースコードを見る
func Index[E comparable](s []E, v E) int { for i := range s { if v == s[i] { return i } } return -1 }
slices.Index() もジェネリクスを使えます。同じく型制約は comparable です。
さて、処理内容ですがシンプルですね。スライスをループし、要素を見つけ次第 index を返します。存在しなかったら -1 を返します。
あるあるなコードだと思いました。
slices.IndexFunc() のソースコードを見る
ついでに見てみます。
func IndexFunc[E any](s []E, f func(E) bool) int { for i := range s { if f(s[i]) { // ここが違う return i }
slices.IndexFunc() は判定処理をカスタマイズできます。jsで言うと Array.prototype.findIndex() に相当するでしょうか。
ソースコードを見れば slices.Index() との違いがよく分かります。関係ないですが、Goはドキュメントにソースコードへのリンクが貼ってあるところが良いですね。親しみやすさを感じます。
Links
作成日
2023-06-05
更新日
2023-12-26