はじめに
こんにちは。DXユニットの村上です。
本記事はGo 1.19リリース連載の5本目です。関数やレシーバのジェネリクスの微修正についてご紹介します。
Release Noteでは次の箇所になります。
https://tip.golang.org/ref/spec#Declarations_and_scope
The scope of an identifier denoting a type parameter of a function or declared by a method receiver begins after the name of the function and ends at the end of the function body.
翻訳すると以下のようになります。
関数の型パラメータやメソッドレシーバで宣言されたもののスコープは、関数名の後ろから関数本体の終端までです。
しかし本アップデートはGo 1.19でリリース予定でしたが、Go 1.20でのリリースに変更されたようです。
https://github.com/golang/go/issues/51503#issuecomment-1154209161
よってGo 1.20リリース予定の紹介という感じになります。
従来の問題点
こちらのissueで問題提起されています。
https://github.com/golang/go/issues/51503
以下のコードが例として提示されています。
type T[T any] struct {} // OK |
前者がOKなら後者もOKであるべきと議論されていました。
原因
後者がビルドエラーとなる原因は以下のissueで説明されています。
https://github.com/golang/go/issues/52038
func (T[T]) Bar() {} |
[T]
のT
が外側(左側)のT
を参照しているため、エラーとなるようです。
逆に外側をT
以外にすればエラーにはなりません。
type Hoge[T any] struct{} // OK |
後者のHoge
、[T]
は前者のHoge
、[T any]
をそれぞれ参照できているため問題ありません。
もしくは[T]
を別の文字に置き換えても大丈夫です。
type T[T any] struct{} // OK |
解決策
冒頭で引用したリリースノートの内容にすることで、これがエラーにならなくなります。
レシーバの中で宣言された型のスコープを関数名以降にします。
これによって、外側のT
のスコープは関数名以降となり、[T]
に適用されなくなります。
おわりに
かなりマイナーアップデートですが、Golangがより洗練された言語になることは間違いないかと思います。
修正範囲が大きいということで惜しくもGo 1.19でのリリースは見送られることになりましたが、Go 1.20では修正されるということで期待したいと思います。