An interface is two things: a set of methods and also a type.
int
where an object with a Read
method was expectedt, ok := i.(T)
asserts the interface value i
holds concrete type T
, assigns it to t
and returns a boolean to ok
(Where T can be the type of interface you are trying to assert).ok
return causes it to panic
if not type T
A core concept of Go's type system is that instead of designing our abstractions in terms of what data a type can hold, abstractions are designed in terms of what actions a type can execute.
type Animal interface { ... }
describes the actions (methods) the type Animal
can performinterface
, it is determined automatically at compile timetype
can then implement mulitple interfaces
interface{}
typeinterface{}
type is the empty interface. It has no methods, so all types implement the empty interface.
interface{}
value as a parameter, it can take any value, assigning not its original type but an interface{}
typefunc DoSomething(v interface{}) {...}
(performs a type conversion, DoSomething(5)
converts int
to interface{}
An interface value is constructed of two words of data
The method table or interface table, is some metadata about the types involved and a list of function pointers.
An interface definition does not explicitly state whether an implementor should implement the interface using a pointer reciever or value reciever
func (c Cat) Speak() string
to a Cat pointer: func (c *Cat) Speak() string
and would still be a valid implementor (potentially leading to bugs)&Cat.Speak()
&Dog.Speak()
works the same as Dog.Speak()
if Speak
had a value receiverfunc (t T)MyMethod(s string)
is of type func(T, string)
: method recievers (T
) are passed into the function by value like any other pass by value call