Understanding Go Interface With Lego
The purpose of interface is to enable unrelated objects to communicate with each other. In order to communicate, both sides must follow a protocol. Like Lego, in order to put 2 pieces of brick together, you need to make sure they can "communicate" with each other. The bottom one's studs will fit the one on top's tubes. The designers (programmers) define the interfaces to let two bricks (objects) to communicate.
Interface in Go works slightly different from other languages. The way your type implements the interface is implicit. As long as your type implements the same methods that declared in the interface. For example, let's define a Washer
interface and it has 2 methods: GetCleaner()
and GetWaterVolume()
.
1package main
2
3import (
4 "fmt"
5)
6
7type ClothWasher struct {
8 target string
9}
10
11type DishWasher struct {
12 target string
13}
14
15type Washer interface {
16 GetCleaner() string
17 GetWaterVolume() int
18}
19
20func StartWashing(w Washer) string {
21 cleaner := w.GetCleaner()
22 progress := fmt.Sprintf("start washing with %s", cleaner)
23
24 return progress
25}
26
27func StopWashing(w Washer) string {
28 vol := w.GetWaterVolume()
29 progress := fmt.Sprintf("rinsing with %d liters of water", vol)
30
31 return progress
32}
33
34func (d DishWasher) GetCleaner() string {
35 return "dishwashing liquid"
36}
37
38func (d DishWasher) GetWaterVolume() int {
39 return 2
40}
41
42func (c ClothWasher) GetCleaner() string {
43 return "detergent"
44}
45
46func (c ClothWasher) GetWaterVolume() int {
47 return 10
48}
49
50func main() {
51 c := ClothWasher{}
52 d := DishWasher{}
53
54 fmt.Println(StartWashing(c)) // start washing with detergent
55 fmt.Println(StopWashing(c)) // rinsing with 10 liters of water
56 fmt.Println(StartWashing(d)) // start washing with dishwashing liquid
57 fmt.Println(StopWashing(d)) // rinsing with 2 liters of water
58}
Now both StartWashing
and StopWashing
accept Washer interface as parameter. Which means as long as a type has both GetCleaner()
and GetWater()
methods, this type has already implicitly implemented Washer interface and able to use StartWashing
and StopWashing
methods directly.
In Go, You may also take the advandage of empty interface in your function paramter. An empty interface as paramter means you can pass in any type of data. But make sure you use it appropriately. For example fmt
package's Println
function takes an empty interface as parameter, which means it can print out any data type. By receiving empty interface in incorrect circumstances might also cause unexpected bug.