Go 1.18 では、ジェネリックはコードの柔軟性を高めるための強力なツールを提供します。ただし、型制約を使用する場合、特定のエラーが発生する理由を理解することが重要です。
次のコードを考慮してください。
type stringer interface { a() string } func do(s stringer) { fmt.Println(s.a()) } func blah[T FooBar]() { t := &T{} do(t) } func main() { blah[foo]() }
コンパイルを試行するときこのコードを実行すると、次のエラーが発生する可能性があります:
cannot use t (variable of type *T) as type stringer in argument to do: *T does not implement stringer (type *T is pointer to type parameter, not type parameter)
このエラーは、ジェネリック型制約の仕組みについての誤解に起因します。なんと関数内の制約 FooBar は、インターフェイス FooBar を満たす型のプレースホルダーです。ただし、変数 t は型パラメーター T へのポインターである T 型です。これは、T 自体が型パラメーターではないため、ストリンガー インターフェイスを満たすことができないことを意味します。
この問題の解決策は、型パラメータ T とストリンガー インターフェイスとの間に関係を導入することです。考えられるアプローチは 2 つあります。
1.明示的なアサーション
任意の型変換を使用して、*T がストリンガー インターフェイスを満たすことを明示的にアサートできます:
func blah[T FooBar]() { t := &T{} do(any(t).(stringer)) }
2。型の構成
または、FooBar と stringer の制約を組み合わせた新しい型を定義できます。
type FooBar[T foo | bar] interface { *T stringer } func blah[T foo | bar, U FooBar[T]]() { var t T do(U(&t)) }
このアプローチでは、stringer を FooBar インターフェイスに埋め込むことで型の安全性を確保し、制約を満たすには T がポインタ型である必要がありますFooBar.
Go でジェネリックスを効果的に操作するには、型制約と型パラメーターの関係を理解することが重要です。明示的なアサーションまたは型合成を通じて、T と stringer の間に関係を導入することで、エラーを解決し、目的の動作を有効にすることができます。
以上がGo のジェネリック型パラメーターが「stringer」インターフェイスを満たさないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。