---
# System prepended metadata

title: 'Day 25 : Golang Interface(3)'
tags: [About Go]

---

# Day 25 : Golang Interface(3)

## 前言
記得一開始學完interface的定義的時候，我好像大概了解它是一群方法的集合，如果某個型別的變數都有實現至些方法，就可以說實現這個介面，但常常又在想這樣的好處是什麼呢?為什麼要有interface。今天試著用前兩天貓貓狗狗的例子，來顯現使用interface的介面。

## Without interface
如果定義了兩個結構體，也就是貓貓和狗狗，他們可能叫聲不同，所以寫了兩個不同的方法，分別回傳Woof和Meow，但如果我們想要印出牠怎麼叫的話要怎麼辦呢，可能就要分別寫兩個函式來印出牠怎麼叫，而這個函式的邏輯明明就一樣，真的有必要寫兩次嗎? 這時就是interface出場的時候了。

```go!
type Dog struct {
	name string
}

type Cat struct {
	name string
}

func main() {
	dog := Dog{name: "White"}
	cat := Cat{name: "Orange"}

	printDogSpeaking(dog)
	printCatSpeaking(cat)

}


func printDogSpeaking(dog Dog) {
	fmt.Println(dog.speak())
}

func printCatSpeaking(cat Cat) {
	fmt.Println(cat.speak())
}


func (dog Dog) speak() string{
	return "Woof!"
}

func (cat Cat) speak() string{
	return "Meow!"
}
```

## With Interface
這邊就生活化一點，把interface看成一個俱樂部好了。先定義一個Pet的俱樂部，裡面每個會員都要會叫(~~好怪?~~)，另外分別定義Dog和Cat兩個型別，這兩個型別的變數剛好都會叫(`speak()`)，所以就可以成為這個俱樂部的會員。進來這個俱樂部就可以拿到一個Pet的徽章，從此你因為有了這個徽章，就可以使用俱樂部的方法了。

就像下面第23行，定義一個Pet俱樂部使用的方法，而因為Dog和Cat都是這個俱樂部的會員，所以可以直接在第18 19行使用該方法，得到和上面沒有使用interface一樣的結果。

```go=
type Pet interface{
    speak() sting
}


type Dog struct {
    name string
}

type Cat struct {
    name string
}

func main() {
    dog := Dog{name: "White"}
    cat := Cat{name: "Orange"}

    printSpeaking(dog)
    printSpeaking(cat)

}

func printSpeaking(p Pet){
    fmt.Println(p.speak())
}


func (dog Dog) speak() string{
    return "Woof!"
}

func (cat Cat) speak() string{
    return "Meow!"
}
```


## Duck typing
用比較生活的例子舉例完，接下來用比較資訊的用語來做個總結好了(~~裝逼?~~)
其實上面我們透過interface做的事情就是實現golang裡面的duck typing & polymophism
duck typing 其實是**動態語言**的特性，關注的是對象如何被使用，而不是對象的類型本身。
先看看Wiki的定義
>*If it walks like a duck and it quacks like a duck, then it must be a duck"*

簡單來說如果某個東西游泳像鴨子、叫聲像鴨子、長的像鴨子，不管牠本身是不是鴨子，我們就可以把牠歸內為鴨子。Go是靜態語言，則是透過interface來實現這個特性。

在上面的例子，在printSpeaking這個函式的參數p是一個Pet介面，但是它可以接受任何擁有 speak() 方法的物件。這意味著 printSpeaking 函式可以接受任何**看起來像Pet(狗狗貓貓)**的物件，而不需要特別宣告實現Pet介面的類別。這就類似Duck typing的概念，只需要判斷該物件是否有所需的方法，而不需要特別宣告狗狗貓貓屬於寵物這個特定介面，非常有趣~~



## References
1. [Duck typing - Wiki](https://en.wikipedia.org/wiki/Duck_typing)
2. [有個性的Go鴨子](https://www.ithome.com.tw/voice/135288)
3. [Go 语言与鸭子类型的关系](https://golang.design/go-questions/interface/duck-typing/)

###### tags: `About Go`