ホームページ >バックエンド開発 >Golang >Go でリフレクションを使用して Nil インターフェイス値を渡すにはどうすればよいですか?

Go でリフレクションを使用して Nil インターフェイス値を渡すにはどうすればよいですか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-11-30 14:10:14310ブラウズ

How Can I Pass a Nil Interface Value Using Reflection in Go?

Go のリフレクションを通じてインターフェイスとして Nil 値を渡す

Go では、インターフェイス引数を使用して関数を定義できます。非 nil インターフェース値を渡すのは簡単ですが、次のような疑問が生じます: == nil チェックを通過させるために、リフレクションを介して nil 値を渡すにはどうすればよいですか?

次の関数を考えてみましょう:

func f(e error) {
    if e == nil {
        fmt.Println("YEY! NIL") // how to get here?
    } else {
        fmt.Println("NOT NIL :(")
    }
}

アプローチ 1:reflect.Zero を使用する

func main() {
    rf := reflect.ValueOf(f)

    nilArg := reflect.Zero(reflect.TypeOf((error)(nil))) // panic: reflect: Zero(nil)
}

このアプローチは次のように失敗します。 Reflect.Zero(reflect.TypeOf((error)(nil))) は、nil 型のゼロ値を作成できないためパニックします。

アプローチ 2: Typeof(&type) を使用する

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 インターフェースでメソッドを呼び出そうとすると、パニックが発生します。

解決策: TypeOf((*error)(nil)).Elem()

を使用して 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。