Go

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 T is concrete, the assertion checks that the dynamic type is exactly T. It is a pointer comparison, and there is no conversion (asserting MyInt to int fails).
  • When T is an interface, the assertion checks whether the dynamic type implements T, 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

All 35 Interfaces, Methods & Embedding questions