Go ジェネリックの「引数の型ストリンガーとして型 *T の変数を使用できません」エラーを理解する
提供されたコード スニペットでは、 stringer 型のパラメータを期待する関数 do を一般的に呼び出そうとしていますが、ポインタを渡しています。代わりに型パラメータ T を使用します。
Go コンパイラは次の理由でエラーを発生させます:
-
型の識別とパラメータ: T は本質的にその制約 FooBar と等価ではありません。したがって、*T は *FooBar または *bar と同じではありません。
-
メソッドがありません: ストリンガー インターフェイスには、a() という名前のメソッドが必要です。現在、foo 型と bar 型はポインター レシーバーにこのメソッドを実装していますが、*T は本質的にこのメソッドを持っていません。
問題の解決
この問題を解決するには、主に 2 つのアプローチがあります:
1.型アサーションによる型安全性のアサート (あまり最適ではありません)
- *T が do 関数内で any(t).(stringer) を使用して stringer を実装していることをアサートします。
- このアプローチT が実際に実装しないとパニックが発生する可能性がありますストリンガー。
2.制約の再定義とジェネリックのカスタマイズ (推奨)
- ストリンガーを制約として FooBar インターフェイスに追加します。
- foo 型と bar 型のポインター レシーバーを使用して制約に合わせます。 .
- FooBar 内の制約を指定する 2 番目の型パラメータを導入します。
- 制約された型のインスタンスを引数として blah に渡します。
改訂コード:
type FooBar[T foo | bar] interface {
*T
stringer
}
func blah[T foo | bar, U FooBar[T]]() {
var t T
do(U(&t))
}
func main() {
blah[foo]()
}
この内改訂されたコード:
- FooBar インターフェイスにはストリンガーが含まれています。制約。
- foo 型と bar 型には、a() メソッドのポインタ レシーバがあります。
- U は FooBar[T] によって制約され、FooBar 制約とストリンガー制約の両方を満たすことが保証されます。
- まあ、型 U の引数を取ります。これは、制約された FooBar のインスタンスです。インターフェース。
以上がGo ジェネリックスで `*T` 型変数を `Stringer` として使用できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。