Golang interfaces
Similar to other languages, interfaces in go define a contract of method-signatures that implementors must have.
Unlike other languages, golang interfaces are implicit -- an object with all of the required methods automatically satisfies an interface.
In go, it is encouraged to keep very small interfaces (ex. 1 method). The larger the interface, the weaker the abstraction.
Similar to other languages, a param can be typed to accept an interface, which abstracts the actual type that is received.
NOTE:
go interfaces define a contract of methods, but not struct fields.
you'll need to define getters/setters for fields
Basics
Libraries do not need to expose interfaces in go, you can create them for the subset of methods that are useful to you.
- An interface is a promise that an object implements a set of method-signatures.
- objects are automatically a part of an interface if they have methods, there is no
implements Foo
- Empty interfaces match all oject types in go. (ex
fmt.Println()
can accept any type)// rectangle.go type Rectangle struct { width int height int } func (rect Rectangle) Area() int { return rect.width * rect.height }// area_calculator.go type AreaCalculator interface { Area() int }// main.go func LargestArea(a, b AreaCalculator) AreaCalculator { if a.Area() > b.Area() { return a } return b } func main() { rect1 := Rectangle{5, 5} rect2 := Rectangle{2, 10} fmt.Println(LargestArea(rect1, rect2) == rect1) }
Interfaces with Pointer Methods
When a method's
self
is a pointer, you must pass in a reference (&value
) to the object in the method call.
Reusing the last example// rectangle.go type Rectangle struct { width int height int } func (rect *Rectangle) Area() int { // <-- SEEME 'rect *Rectangle' indicates this method is added to a reference to this object return rect.width * rect.height }// area_calculator.go -- IDENTICAL type AreaCalculator interface { Area() int }// main.go func LargestArea(a, b AreaCalculator) AreaCalculator { if a.Area() > b.Area() { return a } return b } func main() { rect1 := Rectangle{5, 5} rect2 := Rectangle{2, 10} fmt.Println(rect1.Area()) fmt.Println(rect2.Area()) fmt.Println(LargestArea(&rect1, &rect2)) // <--- SEEME passing in reference!! }
Embedding
Like structs, interfaces can be embedded.
type Walker interface { Walk nil } type BubblegumChewer interface { ChewGum nil } // includes all methods from previous two interfaces type BubblegumChewingWalker interface { Walker BubblegumChewer }
Empty Interfaces
Empty interfaces will accept any type within go.
It is used for example byfmt.Println()
so that it can accept any type of parameter.func typeInfo(obj interface{}) string { fmt.Printf("(%v, %T)\n", obj, obj) }