Compare v := x.(T) with v, ok := x.(T). What happens when T is an interface type?
Question 84MediumGo 1.22 to 1.25
The single-value form panics when the assertion fails. The panic message looks like interface conversion: interface {} is string, not int. The comma-ok form never panics: on failure, ok is false and v is the zero value of T.
var x any = "hello"
s := x.(string) // "hello"
n, ok := x.(int) // 0, false
// n := x.(int) // panic
var r io.Reader = os.Stdin
w, ok := r.(io.Writer) // true: *os.File also has Write
_ = w
var nilIface any
_, ok = nilIface.(any) // false: asserting on a nil interface always fails
_, _ = s, n
- When
Tis concrete, the assertion checks that the dynamic type is exactlyT. It is a pointer comparison, and there is no conversion (assertingMyInttointfails). - When
Tis an interface, the assertion checks whether the dynamic type implementsT, which requires an itab lookup. It succeeds even when the static interface did not include those methods. This is how "optional interface" upgrades work.
A gotcha: asserting on a nil interface fails even when T is any.
More on Interfaces, Methods & Embedding
- Q82Why doesn't
m["k"].Inc()compile whenInchas a pointer receiver? What other values are not addressable? - Q83How do you decide between value and pointer receivers?
- Q85Explain type switch semantics. What does this print?
- Q86Is struct embedding inheritance? How does method promotion work?
- Q87What does this print? (no virtual dispatch with embedding)
- Q88Embedding
Tvs*T: how does each affect the method set of the outer struct?