Go における Nil インターフェイスからポインターへの変換
Go では、インターフェイス型は、それを実装するさまざまな具象型の値を保持できます。ただし、nil インターフェイスを特定の型のポインターに変換しようとすると、「インターフェイス変換: インターフェイスは nil であり、*
この動作を理解するには、質問のコード スニペットを検討してください。
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) // True n = p.(*Node) // Error: interface conversion: interface is nil, not *main.Node }
型アサーション p.(*Node) を使用して p の値を n に代入しようとすると、問題が発生します。 p 変数が nil であるため、このアサーションは失敗します。これは、具体的な値を保持していないことを示しています。
代わりに、次の式:
n = (*Node)(nil)
は、n 変数を明示的に次のように設定しているため成功します。 *Node 型の nil ポインター。これが可能なのは、インターフェース値が (値, 動的タイプ) のペアで構成されており、インターフェース値を nil に設定すると (nil, nil) のペアが作成されるためです。
nil インターフェース値を処理するには、明示的にチェックすることもできます:
if p != nil { n = p.(*Node) // Only succeeds if `p` holds a value of type `*Node` }
あるいは、「カンマOK」形式の type を使用することもできます。 Assertion:
if n, ok := p.(*Node); ok { fmt.Printf("n=%#v\n", n) // Never fails, assigns zero value to `n` if `p` is nil }
結論として、型アサーションを使用して nil インターフェイスを特定の型のポインタに変換しようとすると失敗しますが、明示的に nil に設定すると成功します。 nil インターフェイス値を処理するには、明示的なチェックまたは型アサーションの「カンマ OK」形式を使用できます。
以上がGo で Nil インターフェイスからポインターへの変換が失敗するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。