Implementation of Interfaces

This lesson covers the details about how to test the implementation of interfaces.

Testing if a value implements an interface

This is a special case of the type assertion: suppose v is a value, and we want to test whether it implements the Stringer interface. This can be done as follows:

type Stringer interface { String() string }
if sv, ok := v.(Stringer); ok {
  fmt.Printf("v implements String(): %s\n", sv.String()); // note: sv, not v
}

An interface is a kind of contract, which the implementing type(s) must fulfill. Interfaces describe the behavior of types, specifying what types can do. They completely separate the definition of what an object can do from how it does it, allowing distinct implementations to be represented at different times by the same interface variable, which is what polymorphism essentially is. Writing functions so that they accept an interface variable as a parameter makes them more general.

Note: Use interfaces to make your code more generally applicable.

This is also ubiquitously applied in the code of the standard library. It is impossible to understand how it is built without a good grasp of the interface-concept.

Using method sets with interfaces

In Chapter 8, we saw that methods on variables do not distinguish between values or pointers. When storing a value in an interface type, it is slightly more complicated because a concrete value stored in an interface is not addressable. Still, luckily the compiler flags an error on improper use. Consider the following program:

Get hands-on with 1200+ tech skills courses.