Golang整潔接口最佳實踐

翻譯自:https://qvault.io/2020/03/15/best-practices-for-writing-clean-interfaces-in-go/

woman-3169726_640.jpg

Go中的接口允許我們將不同的類型暫時視為同一數(shù)據(jù)類型痒筒。它們是 Go 程序員工具箱的核心,但新的 Go 開發(fā)者往往會使用不當......導致代碼難以閱讀柄瑰,易于產(chǎn)生Bug。讓我們來看看Golang接口的一些最佳實踐舔糖。

我經(jīng)常以標準庫為例铅鲤,來說明如何寫出干凈的Go接口蕉朵。標準的錯誤接口很簡單:

type error interface {
    Error() string
}

error接口封裝了任何有Error()方法的類型。該方法不接受任何參數(shù)关顷,并返回一個字符串糊秆。例如,讓我們定義一個表示網(wǎng)絡(luò)問題的結(jié)構(gòu)议双。

type networkProblem struct {
    message string
    code    int
}

然后痘番,我們定義一個Error()方法:

func (np networkProblem) Error() string {
    return fmt.Sprintf("network error! message: %s, code: %v", np.message, np.code)
}

Now, we can use an instance of the networkProblem struct wherever an error is accepted.

現(xiàn)在,我們可以在任何接受到錯誤的地方使用networkProblem結(jié)構(gòu)的實例:

func handleErr(err error) {
    fmt.Println(err.Error())
}

np := networkProblem{
    message: "we received a problem",
    code:    404,
}

handleErr(np)

// prints "network error! message: we received a problem, code: 404"

堅持小接口

如果你只能從這篇文章中得到一條建議平痰,那就是:讓接口小一點! 接口的目的是為了定義準確表示一個想法或概念所必需的最小行為汞舱。

下面是標準HTTP包中一個更大的接口的例子,它是定義最小行為的好例子:

type File interface {
    io.Closer
    io.Reader
    io.Seeker
    Readdir(count int) ([]os.FileInfo, error)
    Stat() (os.FileInfo, error)
}

任何滿足接口行為的類型都可以被HTTP包當作一個文件來處理宗雇。這很方便昂芜,因為HTTP包不需要知道它處理的是磁盤上的文件、網(wǎng)絡(luò)緩沖區(qū)赔蒲,還是簡單的[]字節(jié)泌神。

接口應該沒有滿足類型的知識

一個接口不應該關(guān)心具體的類型。

下面舞虱,假設(shè)我們構(gòu)建一個用于描述一輛汽車的組件的接口:

type car interface {
    GetColor() string
    GetSpeed() int
    IsFiretruck() bool
}

GetColor()GetSpeed() 方法是汽車領(lǐng)域的知識欢际。而 IsFiretruck() 則是反模式。此接口應該關(guān)注所有汽車的通用方法矾兜,而不應該關(guān)心它是否是一臺消防車损趋。 否則,我們還必須在這個接口中增加:IsPickup(), IsSedan(), IsTank() 等等椅寺,沒完沒了了浑槽。

相反墙杯,當給定一個car的接口實例時,開發(fā)應該根據(jù)類型斷言的原生功能來推斷出子類型括荡。或者溉旋,如果子接口需要一個子接口畸冲,它可以定義為:

type firetruck interface {
    car
    HoseLength() int
}

firetruck接口繼承了汽車的必要方法,并增加了一個額外的必要方法观腊,使汽車成為消防車邑闲。

接口不是類

接口不是類,應該是小的梧油。

接口不需要構(gòu)造函數(shù)或析構(gòu)函數(shù)苫耸,因為它沒有必要進行數(shù)據(jù)的初始化和銷毀。

接口在本質(zhì)上不是分層的儡陨,盡管有語法糖來創(chuàng)建接口褪子,而這些接口恰好是其他接口的超集。

接口只負責定義函數(shù)簽名骗村,不關(guān)心其具體實現(xiàn)嫌褪。在結(jié)構(gòu)方法中,定義一個接口可以減少重復代碼胚股。例如笼痛,如果5種類型實現(xiàn)了錯誤接口,它們就需要分別實現(xiàn)Error()函數(shù)琅拌。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缨伊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子进宝,更是在濱河造成了極大的恐慌刻坊,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件党晋,死亡現(xiàn)場離奇詭異紧唱,居然都是意外死亡,警方通過查閱死者的電腦和手機隶校,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門漏益,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人深胳,你說我怎么就攤上這事绰疤。” “怎么了舞终?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵轻庆,是天一觀的道長癣猾。 經(jīng)常有香客問我,道長余爆,這世上最難降的妖魔是什么纷宇? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮蛾方,結(jié)果婚禮上像捶,老公的妹妹穿的比我還像新娘。我一直安慰自己桩砰,他們只是感情好拓春,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著亚隅,像睡著了一般硼莽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上煮纵,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天懂鸵,我揣著相機與錄音,去河邊找鬼行疏。 笑死矾瑰,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的隘擎。 我是一名探鬼主播殴穴,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼货葬!你這毒婦竟也來了采幌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤震桶,失蹤者是張志新(化名)和其女友劉穎休傍,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹲姐,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡磨取,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了柴墩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忙厌。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖江咳,靈堂內(nèi)的尸體忽然破棺而出逢净,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布爹土,位于F島的核電站甥雕,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏胀茵。R本人自食惡果不足惜社露,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望琼娘。 院中可真熱鬧峭弟,春花似錦、人聲如沸轨奄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挪拟。三九已至,卻和暖如春击你,著一層夾襖步出監(jiān)牢的瞬間玉组,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工丁侄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惯雳,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓鸿摇,卻偏偏與公主長得像石景,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拙吉,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容