go.devgo.dev
generic methods
Go1.27に generic methods が追加された。今までは package-level function でしかGeneric は使えなかったのが使えるようになった。
# 1.27
# 定義
type Stream[T any] struct {
values []T
}
func (s Stream[T]) Map[U any](f func(T) U) Stream[U] {
// T の Stream を U の Stream に変換する
}
# 使う側
s := Stream[int]{}
mapped := s.Map[string](func(v int) string {
return strconv.Itoa(v)
})
# 1.27以前
# 定義
func Map[T, U any](s Stream[T], f func(T) U) Stream[U]
# 使う側
s := Stream[int]{}
mapped := Map[int, string](s, func(v int) string {
return strconv.Itoa(v)
})
つまり、上記で言えばStream structのメソッドとしてまとめることができるようになった。
method setに置くメリット
1. package設計としてきれい
packageとして整理できることで以下のようなメリットがあるようです。
- 使う側が読みやすい
- エディタ補完で出てくるので発見しやすくなる
- package 直下にfunctionsを増やし続けなくてよくなる
2. 処理の連鎖が書きやすい
これはなるほどなーと思ったところですが、methodに入れることで以下のような繋げ方がしやすくなるようです。
names := users.
Filter(func(u User) bool {
return u.Active
}).
Map(func(u User) string {
return u.Name
}).
Take(10)
Genericsを使いたいケースとして型変換などはよくある例だと思うので、こういった繋げ方をすることで処理が綺麗に描けるようになるというのはありそうだなと感じました。
generic methodはinterfaceを満たさない
generic methodを使うと、結果的にinterfaceで定義したのと同じメソッドを持った構造体ができることがある。 具体的には以下のようなケースである。
type I interface {
f(string)
}
type G[T any] struct {
f(T)
}
# 使う側
g := G[string]{}
g.f("string")
こういった場合にGはinterface Iを満たさない。
ここはたしかにこう言った時どうなるんだろうか?と気になったのでなるほどなと感じた。
size-specialized memory allocation
https://go.dev/doc/go1.27#faster-memory-allocation
80byte未満のメモリアローケーションにおけるコストが30%程度改善した。
どの程度、最適化向きのワークロードで動いているか?にもよるが、頻繁に小さいオブジェクトのアロケーションが発生しているようなものだと全体で1%程度のパフォーマンス改善が見込まれる。
80byte未満のメモリアロケーションが発生するワークロードとは?
ようは「80byte未満の小さいオブジェクトが生成されやすい処理」が、このワークロードに該当する。
主に以下のようなものがある - HTTP Request,Response 処理 - ORMを使ったDBデータのオブジェクト化処理 - JSON decode 処理
どういった時に各オブジェクトがheapになるかの判定はコンパイラのみ知るところで詳細部分はわからないが、こういった部分が改善すると理解した。
なぜパフォーマンスが改善するのか
The compiler now generates calls to size-specialized memory allocation routines,
とある通り、80byte未満のものは size-specialized memory allocation routines という「そのサイズに特化したheap allocation関連処理」に流す。
いままでは汎用的な heap allocation 処理に全部が流れていたが、事前にコンパイラが小さいサイズのallocationとわかっている場合にはより軽量な処理に切り替えることができるようになった。
New uuid package
https://go.dev/doc/go1.27#uuid
Goの標準ライブラリにUUID実装を追加するメリデメ
デメリット:リリースサイクルが固定されることでバグ修正が迅速に反映できない。元の作者以外がメンテすることになりメンテコストが高くなる。後方互換性確保の原則対象になる(これもメンテコストになる)。
メリット:十分に標準ライブラリの要件を満たしているなら、都度外部からimportする必要がなくなる。かつユーザーは継続的なメンテナンスを期待できる。
UUID version 4とUUID version 7だけをサポートする方針
google/uuid ではほぼ v4/v1/v7 しか使われていなかった。 また、RFC9562 では新規利用の際は v1 ではなく v7 を使うように推奨されているためv4,v7のみサポートする方針。















