Pointers 将nil接口转换为Golang中某物的指针?
在以下代码段中,尝试将nil接口转换为某个对象的指针失败,并出现以下错误:Pointers 将nil接口转换为Golang中某物的指针?,pointers,interface,go,Pointers,Interface,Go,在以下代码段中,尝试将nil接口转换为某个对象的指针失败,并出现以下错误:接口转换:接口为nil,而不是*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,而不是*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
}
此处播放链接:
这究竟是为什么失败的呢?这完全有可能做到
n = (*Node)(nil)
,所以我想知道如何从nil接口开始实现类似的效果。这是因为静态类型的变量
Nexter
(它只是一个接口)可能包含许多不同的动态类型的值
是的,由于*Node
实现了Nexter
,因此p
变量可能会保存*Node
类型的值,但它也可能保存实现Nexter
的其他类型;或者它可能什么也不保存(nil
value)。此处不能使用,因为引用规范:
x.(T)
断言x
不是nil
,并且x
中存储的值属于T
类型
但是在你的例子中,x
是nil
。如果类型断言为false,将发生运行时死机
如果将程序更改为使用以下命令初始化p
变量:
var p Nexter = (*Node)(nil)
您的程序将运行并成功键入断言。这是因为接口值实际上以以下形式保存一对:(值,动态类型)
,在这种情况下,p
将不是nil
,而是保存一对(nil,*Node)
;有关详细信息,请参阅
如果您还希望处理接口类型的nil
值,您可以这样显式地检查它:
if p != nil {
n = p.(*Node) // will not fail IF p really contains a value of type *Node
}
或者更好:使用特殊的“逗号ok”形式:
使用“逗号确定”形式:
如果断言成立,ok
的值为true
。否则为false
,n
的值为T
类型的零值在这种情况下不会发生运行时死机。
// This will never fail:
if n, ok := p.(*Node); ok {
fmt.Printf("n=%#v\n", n)
}