天天看點

Go 去找個對象吧

Go 去找個對象吧

我的讀者中應該大部分都是 <code>Java</code> 從業者,不知道寫 <code>Java</code> 這些年是否真的有找到對象?

沒找到也沒關系,總不能在一棵樹上吊死,我們也可以來 <code>Go</code> 這邊看看,說不定會有新發現。

開個玩笑,本文會以一個 <code>Javaer</code> 的角度來聊聊 <code>Go</code> 語言中的面向對象。

面向對象這一詞來源于<code>Object Oriented Programming</code>,也就是大家常說的 <code>OOP</code>。

對于 <code>Go</code> 是否為面向對象的程式設計語言,這點也是讨論已久;不過我們可以先看看官方的說法:

Go 去找個對象吧

其他的我們暫且不看,<code>Yes and No.</code> 這個回答就比較微妙了,為了這篇文章還能寫下去我們先認為 <code>Go</code> 是面向對象的。

面向對象有着三個重要特征:

封裝

繼承

多态

<code>Go</code> 并沒有 <code>Class</code> 的概念,卻可以使用 <code>struct</code> 來達到類似的效果,比如我們可以對汽車聲明如下:

與 <code>Java</code> 不同的是,<code>struct</code> 中隻存儲資料,不能定義行為,也就是方法。

當然也能為 <code>Car</code> 定義方法,隻是寫法略有不同:

在方法名稱前加上 <code>(car *Car)</code> 便能将該方法指定給 <code>Car</code> ,其中的 <code>car</code> 參數可以了解為 <code>Java</code> 中的 <code>this</code> 以及 <code>Python</code> 中的 <code>self</code>,就語義來說我覺得 <code>go</code> 更加簡單一些。

畢竟我見過不少剛學習 <code>Java</code> 的萌新非常不了解 <code>this</code> 的含義與用法。

既然談到結構體了那就不得不聊聊 <code>Go</code> 支援的匿名結構體(雖然和面向對象沒有太大關系)

<code>Go</code> 允許我們在方法内部建立一個匿名的結構體,後續還能直接使用該結構體來擷取資料。

這點在我們調用外部接口解析響應資料時非常有用,建立一個臨時的結構體也不用額為維護;同時還能用面向對象的方式擷取資料。

相比于将資料存放在 <code>map</code> 中用字段名擷取要優雅許多。

<code>Go</code> 語言中并沒有 <code>Java</code>、<code>C++</code> 這樣的繼承概念,類之間的關系更加扁平簡潔。

各位 <code>Javaer</code> 應該都看過這類圖:

Go 去找個對象吧

相信大部分新手看到這圖時就已經懵逼,更别說研究各個類之間的關系了。

不過這樣好處也明顯:如果我們抽象合理,整個系統結構會很好維護和擴充;但前提是我們能抽象合理。

在 <code>Go</code> 語言中更推薦使用組合的方式來複用資料:

這樣我們便可以将公共部分的資料組合到新的 <code>struct</code> 中,并能夠直接使用。

面向接口程式設計的好處這裡就不在贅述了,我們來看看 Go 是如何實作的:

首先定義了一個接口 <code>RunService</code>;<code>ElectricCar</code> 與 <code>PetrolCar</code> 都實作了該接口。

可以看到 <code>Go</code> 實作一個接口的方式并不是 <code>implement</code>,而是用結構體聲明一個相同簽名的方法。

這種實作模式被稱為”鴨子類型“,<code>Python</code> 中的接口也是類似的<code>鴨子類型</code>。

Go 去找個對象吧

詳細介紹可以參考這篇:Python 中的面向接口程式設計

接口當然也是可以擴充的,類似于 <code>struct</code> 中的嵌套:

Go 去找個對象吧

得益于 <code>Go</code> 的強類型,剛才的 <code>struct</code> 也得實作 <code>DiService</code> 這個接口才能編譯通過。

到這裡應該是能了解官方所說的 <code>Yes and No.</code> 的含義了;<code>Go</code> 對面向對象的文法不像 <code>Java</code> 那麼嚴苛,甚至整個語言中都找不到 <code>object(對象)</code> 這個關鍵詞;但是利用 <code>Go</code> 裡的其他特性也是能實作 <code>OOP</code> 的。

是否為面向對象我覺得并不重要,主要目的是我們能寫出易擴充好維護的代碼。

例如官方标準庫中就有許多利用接口程式設計的例子:

Go 去找個對象吧

由于公司技術棧現在主要由 <code>Go</code> 為主,後續也會繼續更新 <code>Go</code> 相關的實戰經驗;如果你也對學習 <code>Go</code> 感興趣那不妨點個關注吧。

作者:

crossoverJie

出處:

https://crossoverjie.top

Go 去找個對象吧

歡迎關注部落客公衆号與我交流。

本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出,

如有問題, 可郵件(crossoverJie#gmail.com)咨詢。