Golang で nil インターフェースを何かのポインターに変換しますか? 質問する

Golang で nil インターフェースを何かのポインターに変換しますか? 質問する

次のコードでは、nil インターフェイスを何かのポインターに変換しようとすると、次のエラーが発生して失敗します。interface conversion: interface is nil, not *main.Node

type Nexter interface {
    Next() Nexter
}

type Node struct {
    next Nexter
}

func (n *Node) Next() Nexter {...}

func main() {
    var p Nexter

    var n *Node
    fmt.Println(n == nil) // will print true
    n = p.(*Node) // will fail
}

再生リンクはこちら:https://play.golang.org/p/2cgyfUStCI

なぜこれが失敗するのでしょうか?

n = (*Node)(nil)

なので、nil インターフェースから始めて同様の効果を実現するにはどうすればよいのか疑問に思っています。

ベストアンサー1

これは、静的Nexter(単なるインターフェース)は、さまざまな値を保持できます。動的種類。

はい、*Nodeを実装しているのでNexterp変数5月型の値を保持します*Nodeが、その他のタイプ実装も同様にNexter、またはそれが保持する可能性がある何もないまったく(nil価値)。そして型アサーション仕様から引用しているため、ここでは使用できません。

x.(T)それxないnilに格納されている値はx型であることを確認しますT

しかし、xあなたの場合は ですnil。そして、型アサーションが偽であれば、実行時パニックが発生する

プログラムを変更してp変数を初期化すると、

var p Nexter = (*Node)(nil)

プログラムは実行され、型アサーションは成功します。これは、インターフェース値が実際には の形式でペアを保持しているためです。(value, dynamic type)この場合、 はpではなくnilのペアを保持します(nil, *Node)。詳細については、リフレクションの法則 #インターフェースの表現

インターフェース型の値も処理したい場合はnil、次のように明示的に確認できます。

if p != nil {
    n = p.(*Node) // will not fail IF p really contains a value of type *Node
}

または、より良い方法として、特別な「カンマOK」形式を使用します。

// This will never fail:
if n, ok := p.(*Node); ok {
    fmt.Printf("n=%#v\n", n)
}

「カンマOK」形式の使用:

アサーションが成立する場合、の値はokです。それ以外の場合は であり、 の値は型 のゼロ値です。truefalsenTこの場合、ランタイムパニックは発生しません。

おすすめ記事