給 Go 庫做者的建議

Golang Practice Advicehtml

視頻信息

Practical Advice for Go Library Authors by Jack Lindamood at GopherCon 2016git

www.youtube.com/watch?v=5v2…github

幻燈地址: go-talks.appspot.com/github.com/…golang

命名

包名是未來使用過程當中的一部分,因此避免重複包名和結構與函數。好比bash

var h client.Client → var h http.Client
複製代碼
context.NewContext() => context.Background()
複製代碼

Object Creation

golang 沒有構造函數,所以建立對象通常有兩種辦法:微信

  • 默認的0值
  • 單獨的構造函數,NewSomething()

推薦使用默認 0 值的構造方法併發

在默認0值的狀況下,各個方法要處理好0值,好比有些東西發現是0值後,給入一個默認值。app

New() 構造函數很靈活,能夠作任何事情,所以對於代碼閱讀上不利,意味着隱藏了不少東西。ide

有些庫使用私有 struct,公開接口的方法,authImpl struct and Auth interface,這是反模式,不推薦使用。函數

不推薦使用 Singleton,雖然標準庫中大量使用了 Singleton 模式,可是 Jack 我的不喜歡這種模式。

使用高階函數做爲選項這種形式不推薦:NewSomething(WithThingA(), WithThingB())

日誌

一些日誌是直接打印到標準輸出去,這是很是很差的設計,由於用戶若是想關根本關不了。

建議

  • 肯定一下做爲是否是真的須要打印日誌,是否是應該把輸出日誌的工做交給調用方決定?
  • 若是必定須要日誌,那麼使用回調函數方式
  • 輸出日誌到一個 interface
  • 不要假定傳進來的就是標準庫的 log ,有不少選擇。
  • 尊重 stdout 和 stderr
  • 不要使用 singleton

interface vs struct

接受 interface ,但返回的是 struct

這點和 Java 不一樣,Java 更傾向於全部東西都是經過 interface 操做。而 golang 不須要,golang 使用的是隱性interface。

何時 panic

最好都不 panic。若是非要 panic,可能最合適的地方是 init 的時候,由於剛一運行就能看到掛了,比較容易處理。但即便如此,也儘可能不要 panic。

檢查 error

問:咱們是須要檢查全部的 error 麼?好比有些彷佛不大容易出錯。 答:須要,特別是你說的這些不大容易出錯的!!

咱們用 error 代替了 exception,因此不要忽略這個東西。

處理的辦法

  • 最好的辦法是 Bubble up,也就是傳回調用方
  • 但有的時候(好比 goroutine) 不適合,那就:
    • 作日誌
    • 或者增長某個計數器

何時應該返回錯誤比較合適?

  • 當不知足約定
  • 當須要的答案沒法獲得

容許啓用庫的調試能力

爲測試而設計

  • 爲了方便本身測試
  • 爲了方便庫用戶測試

併發

channels

雖然 channel 是 golang 一個處理併發很好地東西,可是並不是全部場合都須要。好比標準庫中就不多有在 API 中使用 channel 的。

  • 將使用 channel 的位置向上層移動。
  • 可使用回調函數。
  • 不要混合使用 mutex 和 channel

何時發起 goroutine

  • 有一些庫的 New() 會發起他們的 goroutine,這是很差的。
  • 標準庫使用的是 Serve() 函數。以及對應的 Close() 函數
  • 將 goroutine 向上層推

何時使用 context.Context

  • 全部的阻塞、長時間的操做,都應該能夠被 cancel
  • 因爲 context.Context 很容易存儲東西,因此很容易被濫用。要盡力去避免使用 Context
  • Singleton 和 context.Value() 是一樣性質的東西,像全局變量同樣,對於程序狀態來講是個黑箱。

其它注意事項

  • 若是什麼東西很難作,嗯,那就讓別人去作吧
  • 爲了效率而升級
    • 可是,正確性要比效率重要,在正確性的前提下,注意效率
  • 不要在庫中使用 /vendor (在 main 包中能夠)
  • 注意 build tag
  • 保持乾淨
    • 儘可能使用全部的靜態分析工具來檢查代碼。

原文

blog.lab99.org/post/golang…

博主

我的微信公衆號:

我的github:

github.com/jiankunking

我的博客:

jiankunking.com

相關文章
相關標籤/搜索