将nil接口转换为Golang中某些东西的指针?

时间:2015-05-11 07:51:36

标签: pointers interface go

在下面的代码中,尝试将nil接口转换为某个东西的指针失败,并显示以下错误:var encodedChar = "\(character)".toInt()! + keyNumbers[index] let data = NSData(bytes: &encodedChar, length: 1) encodedData.appendData(data)

interface conversion: interface is nil, not *main.Node

在此处播放链接:https://play.golang.org/p/2cgyfUStCI

为什么这会完全失败?完全可以做到

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
}

,所以我想知道如何从nil界面开始实现类似的效果。

1 个答案:

答案 0 :(得分:25)

这是因为 static 类型Nexter的变量(它只是一个接口)可能包含许多不同动态类型的值。

是的,由于*Node实施Nexter,您的p变量可能保留*Node类型的值,但它可能包含其他类型以及实施Nexter;或者它可能完全没有 nil值)。此处不能使用Type assertion,因为引用了规范:

  

x.(T)断言x 不是nil ,而x中存储的值属于T类型。< / p>

但您的xnil。如果类型断言为假,发生运行时恐慌

如果您更改程序以使用以下内容初始化p变量

var p Nexter = (*Node)(nil)

您的程序将运行并输入断言成功。这是因为接口值实际上以(value, dynamic type)的形式保存了一对,在这种情况下,您的p将不是nil,而是会保留一对(nil, *Node) };有关详细信息,请参阅The Laws of Reflection #The representation of an interface

如果您还想处理接口类型的nil值,可以像这样明确地检查它:

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

或者更好:使用特殊的&#34; comma-ok&#34;形式:

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

使用&#34;逗号&#34;形式:

  

如果断言成立,ok的值为true。否则为falsen的值为类型T的零值。 在这种情况下不会发生运行时恐慌。