将 nil 接口转换为 Golang 中某物的指针?

在以下代码段中,尝试将 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 界面开始实现类似的效果。


慕的地6264312
浏览 205回答 1
1回答

阿波罗的战车

这是因为静态类型的变量Nexter(它只是一个接口)可能包含许多不同动态类型的值。是的,由于*Nodeimplements Nexter,您的p变量可能包含 type 的值*Node,但它也可能包含其他类型的implementation 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}或者更好:使用特殊的“逗号确定”形式:// This will never fail:if n, ok := p.(*Node); ok {    fmt.Printf("n=%#v\n", n)}使用“逗号确定”形式:如果断言成立,ok则值为is true。否则,它false的值n是 type 的零值T。在这种情况下不会发生运行时恐慌。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go