概要
フューチャーのブログを読んでGo 1.22 についてのアップデートを読んでいて面白かった、すぐに利用できる部分のピックアップです。基本的にフューチャーのブログを参考にしていますので興味有る方は元記事読んでみてください!
追記:🚩 2024/02/07 リリースされました
https://go.dev/blog/go1.22
slice を連結する Concat()
API が追加になった
refs: https://future-architect.github.io/articles/20240130a/
更新PR: (#56353)
result := append(n1, append(n2, n3...)...)
↓
result := slices.Concat(n1, n2, n3)
で書けるようになった!
空スライスやnil のときはどうなる?
Golang ではスライスは参照型であり nil で表現することができますが、このときConcat をするとどうなるのか。
結果→エラーにはならず変化がない。nil同士を連結すると空スライスが返される
func main() {
n1 := []int{1, 2}
n2 := []int{10, 20}
var n3 []int // nil で初期化
result := slices.Concat(n1, n2, n3)
fmt.Println(result) // [1 2 10 20]
}
playground: https://go.dev/play/p/lE2iKA8CIxY?v=gotip
func main() {
var n1, n2, n3 []int
result := slices.Concat(n1, n2, n3)
fmt.Println(result) // []
}
playground: https://go.dev/play/p/s8i7dovnC0G?v=gotip
となります。稀なケースですがnilを連結してもnil のまま扱いたい場合は少し注意が必要ですね。
Concat API のソースコードはこちら→ https://cs.opensource.google/go/go/+/master:src/slices/slices.go;l=502
感想
「Concat で書きましょう!」ってレビューができるとモダンなレビューになります。(笑)
HTTPルーティングの強化
Go1.22 リリース連載 HTTPルーティングの強化(**https://future-architect.github.io/articles/20240202a/)
- HTTPメソッドの指定が可能に
mux.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World")
})
- ワイルドカードの指定が可能に
mux.HandleFunc("GET /items/{id}", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "%s", r.PathValue("id"))
})
標準で手が届かない痛い部分だった。できるようになったかー!
感想
- 標準ライブラリでも使いやすくなっていてわりとこれでも良さそう
- ミドルウェアを自分で書かなきゃいけないのはキツイか…?
int での Range がもっとシンプルにりようできるようになった
ref: https://future-architect.github.io/articles/20240206a/
Range over integer というらしい。
以下のように書けるようになった
// 従来の書き方
for i := 0; i < 5; i++ {
fmt.Println(i)
}
↓
// Go 1.22 での新しい書き方(range over integer)
for i := range 5 {
fmt.Println(i)
}
※もちろん従来の書き方もできるよ!
for i := range -1
、 for i := range 0
どうなる?
結果→ループしない
For an integer value n, the iteration values 0 through n-1 are produced in increasing order. If n <= 0, the loop does not run any iterations.
range over integer
の挙動としては
- range に渡された
n
が integer型の場合は- n > 0 ならば、0 から n-1 まで +1 だけインクリメントしながらループを継続する
- n <= 0 ならば、ループしない
(元記事より引用)
goplaygroundでの検証→ https://go.dev/play/p/lEPR3Xrh9gA?v=gotip
- go dev branch にすると1.22 で遊べるよ!
int以外、例えばfor i := range []string{"a","b","c"}
どうなる?
結果→インデックスのみが表示される。
これは従来と同じですね。この書き方自体は go 1.21 以下でもかけます。
他の対象でも同じです。
感想
Python みたいだな。
楽だけどちょっと初見殺し感がある例外的なコードなのはシンプルさが失われているようなきもするとか思ったけど、昨今のアップデートを見るとGoも柔軟になるように変化していっているんだろうな。
おまけ
💡 range に入る第1返り値と第2返り値
感覚でやってたけど厳密な定義↓
Range expression 1st value 2nd value
array or slice a [n]E, *[n]E, or []E index i int a[i] E
string s string type index i int see below rune
map m map[K]V key k K m[k] V
channel c chan E, <-chan E element e E
integer n integer type value i see below