Convert null interface to pointer to something in Golang?

In the following code fragment, an attempt to convert the nil interface to a pointer does interface conversion: interface is nil, not *main.Node 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 } 

Listen to the link here: https://play.golang.org/p/2cgyfUStCI

Why is this not so accurate? This can be done

 n = (*Node)(nil) 

so I wonder how you can achieve a similar effect starting with the nil interface.

+7
pointers interface go
source share
1 answer

This is because a variable of the Nexter static type (which is just an interface) can contain the values โ€‹โ€‹of many different dynamic types.

Yes, since *Node implements Nexter , your p variable may contain a value of type *Node , but it may contain other types that implement Nexter ; or it cannot contain anything at all ( nil value). And the type assertion cannot be used here, as the quote from the specification is:

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

But x in your case is nil . And if the type statement is false, panic occurs at runtime .

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

 var p Nexter = (*Node)(nil) 

Your program will start and enter the approval successfully. This is because the interface value actually contains a pair in the form: (value, dynamic type) , and in this case your p will not be nil , but it will contain a pair (nil, *Node) ; for details see Laws of Reflection # Representation of the interface .

If you also want to handle nil interface type values, you can explicitly check this as follows:

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

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

 // 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 this statement is true . Otherwise, it is false , and n is the null value for type T In this case, there is no panic at runtime.

+21
source share

All Articles