Go Interfaces

In a way, Golang is an Interface oriented language, it doesn’t have such complex OOP concepts such as inheritance or polymorphism.

Concepts of Interfaces

The concept of interfaces is common among strong type languages e.g. C/C++, C#, Java, however it doesn’t exist in Python or Javascript.

Here’s a scenario, if I want to download the contents from TalkGolang. I can do it in Go as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main

import (
"fmt"
"io/ioutil"
"net/http"
)

func retrieve(url string) string {
resp, err := http.Get(url)

if err != nil {
panic(err)
}

defer resp.Body.Close()

bytes, _ := ioutil.ReadAll(resp.Body)
return string(bytes)
}

func main() {
contents := retrieve("https://www.talkgolang.com/")
fmt.Println(contents)
}

In the solution above, there’s a high dependencies between retrieve and main. I want to decoupling them by putting them into different files.

I’ll make a directory infra and create a file urlretriever.go under this folder.

In urlretriever.go file,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package infra

import (
"io/ioutil"
"net/http"
)

type Retreiver struct{}

func (Retreiver) Get(url string) string {
resp, err := http.Get(url)

if err != nil {
panic(err)
}

defer resp.Body.Close()

bytes, _ := ioutil.ReadAll(resp.Body)
return string(bytes)
}

In the entry file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package main

import (
"fmt"
"learngo/interfaces/infra"
)

func getRetriever() infra.Retreiver{
return infra.Retreiver{}
}

func main() {
retriever := getRetriever()
fmt.Println(retriever.Get("https://www.talkgolang.com"))
}

Go is a static language, and interfaces are needed for more decoupling.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
"fmt"
"learngo/interfaces/infra"
)

func getRetriever() infra.Retriever{
return infra.Retriever{}
}

//func getRetriever() testing.Retriever{
// return testing.Retriever{}
//}

type retriever interface {
Get(string) string
}

func main() {
retriever := getRetriever()
fmt.Println(retriever.Get("https://www.talkgolang.com"))
}

Interfaces here enable to change using different structs defined in different files.

In Go Interfaces can be used without even implementing it.