Interface,目的是為了在多種物件中找出共通性,將這個共通性獨立出來。在這篇的範例中,因為程式不大,大家可能會覺得interface這個方法多此一舉,但在實際上稍微有點規模的專案中,有效的運用interface可以讓整體管理更容易、程式碼更容易看懂等好處。
假設我今天需要兩種形狀物件,圓形(circle)和正方形(square)
圓形則是儲存半徑(radius)
type circle {
radius float64
}
正方形是儲存邊長(side)
type square struct {
side float64
}
這時候大家可能會想到求面積,但是圓形和正方形的面積求法一樣嗎?當然不同,這時候沒學過Interface可能會這樣寫
package main
import (
"fmt"
"math"
)
type circle struct {
radius float64
}
type square struct {
side float64
}
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (s square) area() float64 {
return s.side * s.side
}
func main() {
c := circle{2}
s := square{5}
fmt.Println("Circle area: ", c.area())
fmt.Println("Square area: ", s.area())
}
在Go Playground上執行
到這邊大家有沒有發現,圓形和正方形都有形狀(shape)特徵,那不就剛好是Interface的使用最佳時機嗎?
其實和struct長差不多...,那只要任何的struct有interface裡面的所有function,就算是實作了這個interface
type shape interface {
area() float64
}
只要struct實作area() float64就算是達成了shape,注意要一模一樣才算,不可以是area() int也不可以是area(x int) float64
這時候我們的程式碼應該長這樣
package main
import (
"fmt"
"math"
)
type circle struct {
radius float64
}
type square struct {
side float64
}
type shape interface {
area() float64
}
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (s square) area() float64 {
return s.side * s.side
}
func main() {
c := circle{2}
s := square{5}
fmt.Println("Circle area: ", c.area())
fmt.Println("Square area: ", s.area())
}
在Go Playground上執行
這時候可能還沒什麼不同,但先別急
當有了interface之後,就可以將interface當參數傳遞,很方便的!這時候只要是達成shape要求的都算是shape
func info(x shape) {
fmt.Println("This is a " + x)
fmt.Println("The area are " + x.area())
}
這時候全部的程式碼
package main
import (
"fmt"
"math"
)
type circle struct {
radius float64
}
type square struct {
side float64
}
type shape interface {
area() float64
}
func (c circle) area() float64 {
return math.Pi * c.radius * c.radius
}
func (s square) area() float64 {
return s.side * s.side
}
func info(x shape) {
fmt.Println(x.area())
}
func main() {
c := circle{2}
s := square{5}
info(c)
info(s)
}