Golang Interface / OO Note

Rain Wu
Golang 筆記
Published in
4 min readMar 15, 2019

最近迅速的分析完身邊各個看起來頗有趣的坑,也選了幾個跳進去(或者應該說被推進去),估計很快又會到忙碌的狀態了。學習的時間總是十分珍貴,趁著記憶猶新,就來寫一篇 Golang 中讓我大開眼界的 Interface ~

依稀記得...

之前常常透過 Interface 抽象定義各種不同類別間概念相似的行為,並在類別繼承後做為後續實作類別方法所需依循的規範,我自己主要是這樣用 Interface 啦~ 可能其他大大有更深奧的用法。

但 Golang 沒有 Class 這東西啊 Σ(OAO)!!

Golang 以 struct 規劃儲存資料,並在實作所需方法時指定 struct 為目標,用這樣一種鬆耦合的方式來模擬基本的 Class 結構,分離資料並以資料為主體的風格有種被暗示使用 Data- Driven 的感覺~

那 Golang 的 interface 究竟是....@A@?

Well...基本上他還是一樣具有規範方法實作的功能,但是鬆綁了許多,大概就像這樣:

Knight 和 Archer 隱含的實現了 attacker 這個 interface,雖說沒有什麼像是繼承那樣明確的表示,但從 line 35~36 可看出 AnyAttack 只會接受實作 attacker 介面的參數,而兩次的傳入都是合法的,由此可知他們確實實現了 attacker 這個 interface。

這樣子確實大幅提升了靈活度,但後期代碼量一變多如果沒做好分檔可能就會有點難管理了~

模擬多形

Golang 同樣也沒有函數多形的設計,畢竟參數類別匹配也是要花些時間,可能是嫌這過程拖慢了腳步所以就沒這麼設計了@@~ 不過我們仍能用空接口的手法來模擬多形功能。

如果你對於 interface as parameter 感到神奇的話,可以把他想成「我需要一個實現了此接口的物件來當我的參數」這樣。而空接口意味著你不需要實現任何方法就能符合規定,也就是任何物件都能作為參數。

但這樣其實一不小心就會失控,所以我們也可以在方法內部實作 type-switch 判斷來避免悲劇:

巢狀 interface

扯到巢狀這兩個字,先前對於繼承樹或是 HFSM 牽一髮動全身的心理陰影就會慢慢浮現(呵呵..QwQ)~ Golang 的 interface 也可以有巢狀的組織,但由於只有抽象的方法原型,更動的成本不會說非常高,但我自己還是不喜歡讓巢狀架構像疊金字塔一樣聚沙成塔,它的使用方式大概像這樣:

上面代碼在編譯時會出錯,即使 AnyDefend 中僅使用到 warrior 接口的 Defend 方法,但由於其包含 attacker 接口,因此 Barbarian 同樣需實作 Attack 方法(代碼中註解掉的部分)才會是個能合法傳入的參數。

看起來好像沒有封裝

照剛剛的 Code 看起來 Golang 並沒有封裝機制?不,他當然有,只是實現得很低調優雅,命名以大寫字母開頭的能被 package 外部訪問,稱為「導出」,意義上近似於其他語言的 public;反之則無法被外部訪問,相似於 private。

如果你懷疑會不會和 Python3 有同樣的問題,少了 protected 而只有 public 和 private 的機制,並不足以應付人的惰性,最初討論完程式架構與撰寫原則後,後續實作上就各憑良心了(笑~)

其實不必擔心,因為 Golang 用於打包的 package 機制並沒有繼承的設計,因此也不會有 protected 層級相關的問題,把其他語言設計了三、四層甚至更多的隱私層級簡化到只有兩層,寫起來確實省了不少腦力R~

雖然沒有寫很多,不過大致把最基本的都寫上了,真心覺得 Golang 還有很多令我大開眼界的設計,只是我時間不夠無法逐一整理寫成筆記,不過也許很快就會再寫下一篇了哈哈~XD

--

--

Rain Wu
Golang 筆記

A software engineer specializing in distributed systems and cloud services, desire to realize various imaginations of future life through technology.