Interfaces

I have this phobia about having my body penetrated surgically. You know what I mean?


eXistenZ – Ted Pikul

In Go, the word interface is overloaded to mean severaldifferent things. Every type has an interface, which is the set of methodsdefined for that type. This bit of code definesa struct type S with one field, and defines two methods for S. 15

  1. type S struct { i int }
  2. func (p *S) Get() int { return p.i }
  3. func (p *S) Put(v int) { p.i = v }

Defining a struct and methods on it.

You can also define an interface type, which is simplya set of methods. This defines an interface I with two methods:

  1. type I interface {
  2. Get() int
  3. Put(int)
  4. }

S is a valid implementation for interface I, because it defines the twomethods which I requires. Note that this is true even though there is noexplicit declaration that S implements I.

A Go program can use this fact via yet another meaning of interface, which is aninterface value:

  1. func f(p I) { 1
  2. fmt.Println(p.Get()) 2
  3. p.Put(1) 3
  4. }

At 1 we declare a function that takes an interface type as the argument.Because p implements I, it must have the Get() method, which we call at2. And the same holds true for the Put() method at 3. Because Simplements I, we can call the function f passing in a pointer to a value oftype S: var s S; f(&s)

The reason we need to take the address of s, rather than a value of type S,is because we defined the methods on s to operate on pointers, see thedefinition in the code above. This is not a requirement – we could have definedthe methods to take values – but then the Put method would not work asexpected.

The fact that you do not need to declare whether or not a type implements aninterface means that Go implements a form of duck typing [duck_typing]. This is not pure duck typing, because when possible theGo compiler will statically check whether the type implements the interface.However, Go does have a purely dynamic aspect, in that you can convert from oneinterface type to another. In the general case, that conversion is checked atrun time. If the conversion is invalid – if the type of the value stored inthe existing interface value does not satisfy the interface to which it is beingconverted – the program will fail with a run time error.

Interfaces in Go are similar to ideas in several other programming languages:pure abstract virtual base classes in C++, typeclasses in Haskell or duck typingin Python. However there is no other language which combines interface values,static type checking, dynamic run time conversion, and no requirement forexplicitly declaring that a type satisfies an interface. The result in Go ispowerful, flexible, efficient, and easy to write.