LoginSignup
11
2

Go 1.21で注目したい機能

Last updated at Posted at 2023-08-24

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パッケージはぱっと見使いどこがピンと来なかったのですが、より複雑な実装をする際にはあると嬉しい場面もありそう?

11
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
2