Go Interface介紹

Posted by Kubeguts on 2018-07-05

用生活化的例子來舉例:

Water-pipeline就像是個interface 你就只能灌液體進去,不能塞非液體的東西到 water-pipeline

再用火車鐵軌為例:
Railroads 是train 的 interfaces 不管train上面載的什麼物體,看是passengers 還是cargos

但train的寬度 (width of the train) 都必須要符合鐵軌寬度。


故 railroads 的 interfaces會有以下的組成要素:

1
2
3
type RailRoadWidthChecker interface {
CheckRailsWidth() int
}

RailRoadWidthChecker 規範了 train必須要實作檢查火車自身的width,確保train的width是剛好符合 railroad 的寬度

1
2
3
type RailRoad struct {
Width int
}

// 只有宣告為type RailRoad才能呼叫 IsCorrectSizeTrain

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func (railroad *RailRoad) IsCorrectSizeTrain (trainInstance RailRoadWidthChecker) bool {
return trainInstance.CheckRailsWidth() == railroad.Width
}
```
|| 疑問:為何不是在input中type為Train ???
|| Answer: 因為由struct type為 Train實作了 struct type: RailRoadWidthCheck的CheckRailWidth()的方法

IsCorrectSizeTrain 會接受了一個有實作 interface instance的火車,並且回傳該火車寬度是否與鐵軌相同
```go
type Train struct {
TrainWidth int
}

// 宣告為Train的struct instance 實作 checkRailsWidth()函式 並回傳 int型態
func (p Train) CheckRailsWidth() int {
Return p.TrainWidth
}

接下來用 兩台train 一個有符合railroad寬度 一個則沒符合寬度 來作為範例

1
2
3
4
5
6
7
8
9
10
11
12
func main() {
railroad := RailRoad{Width: 10}

passengerTrain := Train { TrainWidth: 10 }
cargoTrain := Train { TrainWidth: 15 }
// interface要求type為Train必須要實作 CheckRailsWidth
canPassengerTrainPass := railroad.IsCorrectSizeTrain(passengerTrain)
canCargoTrainPass := railroad.IsCorrectSizeTrain(cargoTrain)

fmt.Printf(“Can passengerTrain pass? :%t \n”, canPassengerTrainPass)
fmt.Printf(“Can cargoTrain pass? :%t \n”, canCargoTrainPass)
}

輸出:

1
2
Can passengerTrain pass? :true
Can cargoTrain pass? :false