Type assertions
… If
T
is an interface type,x.(T)
asserts that the dynamic type ofx
implements the interfaceT
.
This simple sentence has some pretty profound implications.
Let’s start with a simple example:
type Fooer interface {
Foo()
}
type thing int
func (thing) Foo() {}
var x interface{} = thing(3)
x.(Fooer) // Valid, the result is an interface of type Fooer
This can be very useful to convert from the empty interface (aka interface{}
or any
) to a more specific interface, as in the above example.
It can also be used to convert from other general interfaces to more specific interfaces. For example, a question that comes up now and again on StackOverflow, is “How do I convert an io.ReadCloer
to an io.Reader
?” Well, one way is with such a type assertion. You may want to consult the definitions, if you’re not familiar.
var rc io.ReadCloser = /* some value */
var r = rc.(io.Reader) // r doesn't have access to the Close() method now.
We can even go one step further, and do something sometimes called “interface smuggling”, but that requires one further concept we’ll be looking at tomorrow. so stay tuned!
Quotes from The Go Programming Language Specification Version of August 2, 2023