Mih*_*gea 14 pointers interface go
在下面的代码片段中,尝试将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
}
Run Code Online (Sandbox Code Playgroud)
点击此处播放链接:https://play.golang.org/p/2cgyfUStCI
为什么这会完全失败?这完全有可能
n = (*Node)(nil)
Run Code Online (Sandbox Code Playgroud)
,所以我想知道如何从nil接口开始实现类似的效果.
icz*_*cza 30
这是因为静态类型的变量Nexter(它只是一个接口)可能包含许多不同动态类型的值.
是的,因为*Nodeimplements Nexter,你的p变量可能包含一个类型的值*Node,但它也可以包含其他类型的实现Nexter; 或者根本没有任何东西(nil价值).而且这里不能使用Type断言,因为引用了规范:
x.(T)断言x是不nil和存储在值x是类型的T.
但x在你的情况下是nil.如果类型断言为假,则会发生运行时混乱.
如果您更改程序以初始化p变量:
var p Nexter = (*Node)(nil)
Run Code Online (Sandbox Code Playgroud)
您的程序将运行并键入断言成功.这是因为接口值实际上以以下形式持有一对:(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
}
Run Code Online (Sandbox Code Playgroud)
或者更好:使用特殊的"逗号 - 确定"形式:
// This will never fail:
if n, ok := p.(*Node); ok {
fmt.Printf("n=%#v\n", n)
}
Run Code Online (Sandbox Code Playgroud)
使用"逗号 - 确定"表单:
如果断言成立,
ok则值为true.否则它是false,并且值n是类型的零值T.在这种情况下不会发生运行时恐慌.
| 归档时间: |
|
| 查看次数: |
18546 次 |
| 最近记录: |