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)
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.