将nil接口转换为Golang中某些东西的指针? [英] Convert nil interface to pointer of something in 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)
您的程序将运行并键入断言成功。这是因为一个接口值实际上以 如果你还想处理 或更好:使用特殊的comma-ok形式: 使用comma-ok表单: In the following code piece, trying to convert a nil interface to a pointer of something fails with the following error: Play link here: https://play.golang.org/p/2cgyfUStCI Why does this fail exactly? It's entirely possible to do , so I'm wondering how can you achieve a similar effect starting from a nil interface. This is because a variable of static type Yes, since But If you change your program to initialize your Your program will run and type assertion succeeds. This is because an interface value actually holds a pair in the form of: If you also want to handle Or better: use the special "comma-ok" form: Using the "comma-ok" form: The value of
这篇关于将nil接口转换为Golang中某些东西的指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!(value,dynamic type)
形式保存一对,在这种情况下,您的 p
不会是 nil
,但会保存一对(nil,* Node)
;有关详情,请参阅。
nil
接口类型的值,你可以像这样明确地检查它:
if p!= nil {
n = p。(* Node)//将不会失败如果p真的包含一个类型值* Node
}
//这将会永远不会失败:
如果n,ok:= p。(* Node); OK {
fmt.Printf(n =%#v \ n,n)
}
$ b
ok <如果断言成立,code>是
true
。否则它是 false
并且 n
的值是类型 T
。 在这种情况下不会发生运行时恐慌。
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
}
n = (*Node)(nil)
Nexter
(which is just an interface) may hold values of many different dynamic types.*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
.x
in your case is nil
. And if the type assertion is false, a run-time panic occurs.p
variable with:var p Nexter = (*Node)(nil)
(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.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
}
// This will never fail:
if n, ok := p.(*Node); ok {
fmt.Printf("n=%#v\n", n)
}
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.