不明なインターフェイスに対する Go の型アサーション
リフレクションを通じてオブジェクトの値を取得し、型アサーションを実行して実際のオブジェクトを取得するプロセス。
obj := new(User) out := reflect.ValueOf(obj).Elem().Interface().(User) fmt.Println(out == *obj) // true
のようなメソッドがよく知られています。ただし、オブジェクトのタイプが事前に不明な場合には問題が発生します。未知のインターフェイスを受け入れる関数を考えてみましょう。
func Foo(obj interface{}) bool { // out := reflect.ValueOf(obj).Elem().Interface().( ... ) return out == *obj } func main() { obj := new(User) fmt.Println(Foo(obj)) }
Foo 関数では、渡されるオブジェクトのタイプを判断することはできません。このため、このようなシナリオで型アサーションをどのように実行できるのかという疑問が生じます。
答えは型アサーションの性質にあります。型アサーションを使用すると、静的に型を検証できないインターフェイスを操作する場合でも、Go で静的型チェックを活用できます。この機能は次の原則に基づいて動作します。
型 t の静的に型付けされた変数 s が与えられると、コンパイラーは s が常に型 t のままであることを保証します。 s が別の型として使用されると、確立された保証に違反するため、コンパイルが拒否されます。
次に、インターフェイス変数 i を想像してください。その型はコンパイル時に分からないため、コンパイラは、i を s に代入しても、s が t 型であるという保証を破らないことを保証できません。型アサーションは、「型が一致するかどうかを実行時に検証し、一致する場合にのみ代入を実行する」と規定することで、この問題を克服します。コンパイラーは、型に互換性がある場合にのみ代入が行われると信頼し、 s が t 型であるという保証を維持するため、このアプローチを承認します。
本質的に、これは実行時に次のことが起こることを意味します:
if (i has type t) { s = i } else { s = t{} // Zero value of t }
要求された機能が不可能なのは、チェックを実行する対象の型をコンパイラが認識する必要があるためです。この知識がなければ、 の静的型を決定できず、検証プロセスが実行不可能になります。
以上がGo で未知のインターフェイスを使用して型アサーションを実行するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。