The Go language has interface types as features, analogous to C-style interfaces. Go's interface types, though, don't seem to be enforced -- they merely define protocol without actually being applied to a type. As they are not enforced, is it still a good idea to use interfaces?
-
6What do you mean by "enforce"? A value must implement an interface in order to be assigned to it, and this is enforced by the type checker. You don't have to declare that a type implements an interface, but this is by design and isn't an issue. – SteveMcQwark Jun 15 '12 at 17:38
-
6What are "C-style interfaces"? And what do you mean that Go doesn't "enforce" interfaces? The Go compilers certainly enforce that when you pass a type to a function that takes a certain interface, the interface is fulfilled, it does this statically at compile time, and is one of the things that makes Go great. – uriel Jun 15 '12 at 18:38
-
1-1: this question is based on the incorrect notion that Go's interfaces are not enforced. http://play.golang.org/p/V65p3FMvPO – weberc2 Oct 23 '14 at 21:32
-
If you don't feel you need to, don't add an interface. If you see a benefit, then add an interface. Interfaces can be added on-the-fly ad hoc. See https://stackoverflow.com/questions/11054830/if-gos-interfaces-arent-enforced-are-they-necessary/62297796#62297796. – Jul 10 '20 at 07:13
-
Only use if you see a benefit. Decouple code. See https://stackoverflow.com/a/62297796/12817546. Call a method “dynamically”. See https://stackoverflow.com/a/62336440/12817546. Access a Go package. See https://stackoverflow.com/a/62278078/12817546. Assign any value to a variable. See https://stackoverflow.com/a/62337836/12817546. – Jul 10 '20 at 10:07
3 Answers
Yes. Go doesn't allow you to build type-hierarchies, so interfaces are very important to allow some polymorphism. Consider the sort.Interface
defined in the package sort
:
type Interface interface {
// Len is the number of elements in the collection.
Len() int
// Less returns whether the element with index i should sort
// before the element with index j.
Less(i, j int) bool
// Swap swaps the elements with indexes i and j.
Swap(i, j int)
}
The sort
package contains a function sort(data Interface)
that expects any object that implements this interface. Without interfaces, such form of polymorphism would not be possible in go. The fact that you don't have to explicitly annotate that your type implements this interface, is irrelevant.
The cool part about go is that you can even implement this interface on primitive types, as long as the type is defined in the same package. So the following code defines a sortable array of integers:
type Sequence []int
// Methods required by sort.Interface.
func (s Sequence) Len() int {
return len(s)
}
func (s Sequence) Less(i, j int) bool {
return s[i] < s[j]
}
func (s Sequence) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}

- 18,779
- 5
- 48
- 56
-
4"you can even implement this interface on primitive types" You mean that you can define methods for custom types, which may be structurally equal to a primitive type. `Sequence` and `[]int` are different types. – newacct Jun 15 '12 at 20:12
-
Couldn't you just define those same methods on `[]int` instead of `Sequence` and actually accomplish the OA's goal? Or can you not write new methods for the primitive types. – matthias Jun 18 '12 at 03:42
-
mathias: Saw this randomly a year+ later, but no, can't define new methods on basic types. – twotwotwo Nov 19 '13 at 18:58
Yes, it is still an excellent idea to use interfaces. Go emphases interfaces. See https://talks.golang.org/2014/go4gophers.slide#5. Extending @ElianEbbing outstanding answer, methods on any types and ad hoc interfaces make for a light-weight OO programming style. See https://talks.golang.org/2012/goforc.slide#48.
An example might illustrate this.
package main
import . "fmt"
func main() {
c.Cry() // Meow
Cryer.Eat(c) // Fish
}
var c = cat{"Fish"}
type cat struct{ s string }
type Eater interface{ Eat() }
type Cryer interface {
Cry()
Eater
}
func (c cat) Eat() { Println(c.s) }
func (cat) Cry() { Println("Meow") }
The Cryer
interface lets you access both the Cry()
and Eat()
methods. See https://talks.golang.org/2012/zen.slide#16. You can add Cryer
to the underlying code without its alteration. See https://stackoverflow.com/a/11753508/12817546. And the code works fine if we remove it. You can still access a method directly as shown by c.Cry()
. This is because Go lets you do two things.
First, you can implement an interface implicitly. An interface is simply a set of methods. See https://talks.golang.org/2013/go4python.slide#33. An interface variable can store any non-interface value as long as it implements the interface's methods. See https://blog.golang.org/laws-of-reflection. Values of any type that implement all methods of an interface can be assigned to a variable of that interface. See https://talks.golang.org/2014/taste.slide#20.
c
is a variable of cat
. cat
implements the Eat()
and Cry()
methods. Eater
explicitly implements Eat()
. Cryer
explicitly implements Cry()
and Eat()
. Therefore cat
implicitly implements the Eater
and Cryer
interface. See https://talks.golang.org/2012/goforc.slide#40. Thus c
a variable of cat
can be a variable of Eater
and Cryer
. See https://golang.org/doc/effective_go.html#blank_implements.
Second, struct and interface types can be embedded in other struct and interface types. See https://golang.org/doc/effective_go.html#embedding. Cryer.Eat(c)
calls Eat()
since it embeds Eater
. Interfaces in Go are thus the primary means for decoupling components of our programs. See https://www.reddit.com/r/golang/comments/6rwq2g. And why interfaces can provide a nice API between packages, clients or servers. See https://stackoverflow.com/a/39100038/12817546.
If you don’t see a benefit, then don’t add an interface. See the comment in https://stackoverflow.com/a/39100038/12817546. There is no explicit hierarchy and thus no need to design one! See https://talks.golang.org/2012/goforc.slide#46. Add an interface when you need it. Define your data types first and build your 1-3 method(s) interface
as you go along. See https://stackoverflow.com/a/11753508/12817546. Quotes edited to match example.
-
Decouple code with an interface. See https://stackoverflow.com/a/62297796/12817546. Call a method “dynamically”. See https://stackoverflow.com/a/62336440/12817546. Access a Go package. See https://stackoverflow.com/a/62278078/12817546. Assign any value to a variable. See https://stackoverflow.com/a/62337836/12817546. – Jul 10 '20 at 09:18
I hope to know what a type check, both statical and at run time is, but I have no idea what is to "enforce an interface".

- 87,403
- 16
- 175
- 139