Go では、インターフェイス引数を使用して関数を定義できます。非 nil インターフェース値を渡すのは簡単ですが、次のような疑問が生じます: == nil チェックを通過させるために、リフレクションを介して nil 値を渡すにはどうすればよいですか?
次の関数を考えてみましょう:
func f(e error) { if e == nil { fmt.Println("YEY! NIL") // how to get here? } else { fmt.Println("NOT NIL :(") } }
func main() { rf := reflect.ValueOf(f) nilArg := reflect.Zero(reflect.TypeOf((error)(nil))) // panic: reflect: Zero(nil) }
このアプローチは次のように失敗します。 Reflect.Zero(reflect.TypeOf((error)(nil))) は、nil 型のゼロ値を作成できないためパニックします。
type MyError struct{} func (e MyError) Error() string { return "" } func main() { rf := reflect.ValueOf(f) nilArg := reflect.Zero(reflect.TypeOf(&MyError{})) // NOT NIL :( }
このアプローチは、Go FAQ の nil エラーに関する項目によっても失敗します。この項目には、インターフェイスの型が nil であるか、特定の型を指す可能性があると記載されています。特に nil を渡すことは正常ではありません。 nil インターフェースでメソッドを呼び出そうとすると、パニックが発生します。
を使用して nil を適切に渡します。リフレクション経由で値を取得するには、式reflect.TypeOf((*error)(nil)).Elem()を使用して、エラーインターフェイスのreflect.Typeを取得します。この式は非インターフェイス値を作成し、リフレクション メソッドを使用して目的のリフレクト タイプを取得します。
次のように nilArg を作成します。
nilArg := reflect.Zero(reflect.TypeOf((*error)(nil)).Elem())
このアプローチでは、nilArg を指定して f を呼び出すと出力されます。 "YEY! NIL."
実際に動作する実装については、プレイグラウンドの例を参照してください。
以上がGo でリフレクションを使用して Nil インターフェイス値を渡すにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。