Golang interfaces: Difference between revisions
No edit summary |
|||
Line 114: | Line 114: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
</blockquote><!-- Embedding --> | </blockquote><!-- Embedding --> | ||
= Empty Interfaces = | |||
<blockquote> | |||
Empty interfaces will accept any type within go.<br> | |||
It is used for example by <code>fmt.Println()</code> so that it can accept any type of parameter. | |||
<syntaxhighlight lang="go"> | |||
func typeInfo(obj interface{}) string { | |||
fmt.Printf("(%v, %T)\n", obj, obj) | |||
} | |||
</syntaxhighlight> | |||
</blockquote><!-- Empty Interfaces --> |
Revision as of 15:58, 6 June 2022
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.
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) }