Goの1.21がリリースされましたね!
なんといっても今回特筆すべきはslicesパッケージの登場だと思います
多言語を扱うエンジニアさんはGoのスライスに扱いづらさを感じた方も多いんじゃないでしょうか
他の言語と遜色ない機能が追加、かつ直感的な関数名のものが増えたので自分が嬉しいなと思った物を紹介したいです
slicesパッケージ
Contains
sのスライス内にvが存在するかをチェックし、存在すればtrueが返ります
func Contains[S ~[]E, E comparable](s S, v E) bool
m := []string{"taro", "jiro", "saburo"}
ok := slices.Contains(m, "jiro")
fmt.Println(fmt.Sprintf("%t", ok)) // true
以前はどうやっていたか
func contains(slice []string, key string) bool {
m := make(map[string]struct{}, len(slice))
for _, s := range slice {
m[s] = struct{}{}
}
_, ok := m[key]
return ok
}
Insert / Delete
Insert:sのスライス内iの位置にvを追加して返します
Delete:sのスライス内にある要素をiからjの位置まで削除して返します
func Insert[S ~[]E, E any](s S, i int, v ...E) S
func Delete[S ~[]E, E any](s S, i, j int) S
m := []string{"taro", "jiro", "saburo"}
m = slices.Insert(m, len(m), "siro")
fmt.Println(fmt.Sprintf("%v", m)) // [taro jiro saburo siro]
m = slices.Delete(m, len(m)-1, len(m))
fmt.Println(fmt.Sprintf("%v", m)) // [taro jiro saburo]
以前はどうやっていたか
m := []string{"taro", "jiro", "saburo"}
m = append(m, "siro")
fmt.Println(fmt.Sprintf("%v", m)) // [taro jiro saburo siro]
m = append(m[:len(m)-1], m[len(m):]...)
fmt.Println(fmt.Sprintf("%v", m)) // [taro jiro saburo]
Index
func Index[S ~[]E, E comparable](s S, v E) int
sのスライス内にvが存在する位置を返します。存在しなければ-1が返ります
サンプル
m := []string{"taro", "jiro", "saburo"}
searchKeys := []string{"jiro", "siro"}
for _, skey := range searchKeys {
if idx := slices.Index(m, skey); idx != -1 {
fmt.Println(fmt.Sprintf("%s is found.", m[idx]))
continue
}
fmt.Println(fmt.Sprintf("%s is not found.", skey))
}
// jiro is found.
// siro is not found.
サンプルケース
スライス内のとある文字を削除したい
import (
"fmt"
"slices"
)
// jiroを消したい
func main() {
m := []string{"taro", "jiro", "saburo"}
if idx := slices.Index(m, "jiro"); idx != -1 {
m = slices.Delete(m, idx, idx+1)
}
fmt.Println(fmt.Sprintf("%v", m)) // [taro saburo]
}
スライス内に指定の文字が無かったら挿入したい
import (
"fmt"
"slices"
)
func main() {
m := []string{"taro", "jiro", "saburo"}
if exists := slices.Contains(m, "siro"); !exists {
m = slices.Insert(m, len(m), "siro")
}
fmt.Println(fmt.Sprintf("%v", m)) // [taro jiro saburo siro]
}
最後に
記事内では触れていませんが、それぞれ比較ロジックをカスタマイズできる関数も用意されていて、かゆいところにも手が届きそうです
sortパッケージはパフォーマンス改善のみがされたようで、つくに追加の機能はない模様
mapsパッケージはぱっと見使いどこがピンと来なかったのですが、より複雑な実装をする際にはあると嬉しい場面もありそう?