将nil接口转换为Golang中某些东西的指针? [英] Convert nil interface to pointer of something in Golang?

查看:490
本文介绍了将nil接口转换为Golang中某些东西的指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码片段中,尝试将nil接口转换为某个指针的某个指针会失败,并显示以下错误: interface conversion:interface is nil,not * main.Node

 键入Nexter界面{
Next()Nexter
}

类型Node结构{
next Nexter
}

func(n * Node)Next()Nexter {...}

func main() {
var p Nexter

var n * Node
fmt.Println(n == nil)//将打印出真正的
n = p。(* Node)/ /将失败
}

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



为什么这完全失败?完全可以这样做:
$ b

  n =(* Node)(nil)

,所以我想知道如何从零接口开始获得类似的效果。

解决方案

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

是的,因为 * Node implements Nexter ,您的 p 变量 may 可以保存 * Node ,但它可能包含其他类型以及实现 Nexter ;或者根本就没有任何东西( nil value)。而类型断言在这里不能使用,因为从规范中引用:


x。(T)断言 x strong>不是 nil ,并且存储在 x 中的值的类型是 T


但在您的情况下 x nil 。如果类型声明为false,发生运行时恐慌



如果将程序更改为初始化 p 变量与:

  var p Nexter =(* Node)(nil)

您的程序将运行并键入断言成功。这是因为一个接口值实际上以(value,dynamic type)形式保存一对,在这种情况下,您的 p 不会是 nil ,但会保存一对(nil,* Node);有关详情,请参阅

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

  if p!= nil {
n = p。(* Node)//将不会失败如果p真的包含一个类型值* Node
}

或更好:使用特殊的comma-ok形式:

  //这将会永远不会失败:
如果n,ok:= p。(* Node); OK {
fmt.Printf(n =%#v \ n,n)
}

使用comma-ok表单:
$ b


ok <如果断言成立,code>是 true 。否则它是 false 并且 n 的值是类型 T 在这种情况下不会发生运行时恐慌。



In the following code piece, trying to convert a nil interface to a pointer of something fails with the following error: 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
}

Play link here: https://play.golang.org/p/2cgyfUStCI

Why does this fail exactly? It's entirely possible to do

n = (*Node)(nil)

, so I'm wondering how can you achieve a similar effect starting from a nil interface.

解决方案

This is because a variable of static type Nexter (which is just an interface) may hold values of many different dynamic types.

Yes, since *Node implements Nexter, your p variable may hold a value of type *Node, but it may hold other types as well which implement Nexter; or it may hold nothing at all (nil value). And Type assertion cannot be used here because quoting from the spec:

x.(T) asserts that x is not nil and that the value stored in x is of type T.

But x in your case is nil. And if the type assertion is false, a run-time panic occurs.

If you change your program to initialize your p variable with:

var p Nexter = (*Node)(nil)

Your program will run and type assertion succeeds. This is because an interface value actually holds a pair in the form of: (value, dynamic type), and in this case your p will not be nil, but will hold a pair of (nil, *Node); for details see The Laws of Reflection #The representation of an interface.

If you also want to handle nil values of interface types, you may check it explicitly like this:

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

Or better: use the special "comma-ok" form:

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

Using the "comma-ok" form:

The value of ok is true if the assertion holds. Otherwise it is false and the value of n is the zero value for type T. No run-time panic occurs in this case.

这篇关于将nil接口转换为Golang中某些东西的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆