Nil Interface to Pointer Conversion in Go
In Go, an interface type can hold values of different concrete types that implement it. However, attempting to convert a nil interface to a pointer of a specific type can result in the error "interface conversion: interface is nil, not *
To understand this behavior, consider the code snippet from the question:
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) // True n = p.(*Node) // Error: interface conversion: interface is nil, not *main.Node }
The problem arises when attempting to assign the value of p to n using the type assertion p.(*Node). This assertion fails because the p variable is nil, indicating that it does not hold any concrete value.
Alternatively, the following expression:
n = (*Node)(nil)
succeeds because it explicitly sets the n variable to a nil pointer of type *Node. This is possible because an interface value consists of a pair of (value, dynamic type), and setting an interface value to nil will result in a pair of (nil, nil).
To handle nil interface values, you can check it explicitly:
if p != nil { n = p.(*Node) // Only succeeds if `p` holds a value of type `*Node` }
Alternatively, you can use the "comma-ok" form of type assertion:
if n, ok := p.(*Node); ok { fmt.Printf("n=%#v\n", n) // Never fails, assigns zero value to `n` if `p` is nil }
In conclusion, attempting to convert a nil interface to a pointer of a specific type using type assertion will fail, but explicitly setting it to nil will succeed. To handle nil interface values, explicit checks or the "comma-ok" form of type assertion can be used.
The above is the detailed content of Why Does a Nil Interface to Pointer Conversion Fail in Go?. For more information, please follow other related articles on the PHP Chinese website!