成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

我們應該怎么樣編寫 Go 語言庫,有哪些標準可以參考?

開發 后端
不久前我和朋友們想出一個主意,準備合并我們的 IRC bots,并用 Go 重寫它們。為了防止重寫大部分現有功能,我們試圖找到支持 bots 程序中使用的 Web API 的現有庫。我們的項目需要一個 Reddit API 的庫。這篇文章啟發于我找到的前三個庫,我不打算說出它們的名字,以免羞辱它們的作者。

 不久前我和朋友們想出一個主意,準備合并我們的 IRC bots,并用 Go 重寫它們。為了防止重寫大部分現有功能,我們試圖找到支持 bots 程序中使用的 Web API 的現有庫。我們的項目需要一個 Reddit API 的庫。這篇文章啟發于我找到的前三個庫,我不打算說出它們的名字,以免羞辱它們的作者。

[[314065]]

上面說的每一個庫都存在一些基本問題以至于它們在真實場景中不可用。并且每個庫都以這樣一種方式編寫:不以非向后兼容的方式修改現有庫的 API,這樣是不可能修復問題的。不幸的是,由于很多其他的庫也存在同樣的問題,所以我會在下面列出一些作者錯誤的地方。

不要對 HTTP 客戶端硬編碼

很對庫都包含了對 http.DefaultClient 的硬編碼。雖然對庫本身來說這并不是問題,但是庫的作者并未理解應該怎樣使用 http.DefaultClient 。正如 default client 建議它只在用戶沒有提供其他 http.Client 時才被使用。相反的是,許多庫作者樂意在他們代碼中涉及 http.DefaultClient 的部分采用硬編碼,而不是將它作為一個備選。這會導致在某些情況下這個庫不可用。

首先,我們很多人都讀過這篇講述 http.DefaultClient 不能自定義超時時間的文章《Don’t use Go’s default HTTP client (in production)[1]》,當你沒法保證你的HTTP 請求一定會完成(或者至少要等一個完全無法預估時間的響應)時,你的程序可能會遇到奇怪的 goroutine 泄漏和一些無法預知的行為。在我看來,這會是每一個對 http.DefaultClient 采用硬編碼的庫不可用。

其次,網絡需要一些額外的配置。有時候需要用到代理,有時候需要對 URL 進行一丟丟的改寫,甚至可能 http.Transport 需要被一個定制的接口替換。當一個程序員在你的庫里用他們自己的 http.Client 實例時,以上這些都很容易被實現。

在你的庫中處理 http.Client 的推薦方式是使用提供的客戶端,但是如果需要的話,有一個默認的備選:

 

  1. func CreateLibrary(client *http.Client) *Library {    if client == nil {        client = http.DefaultClient    }    ...} 

或者如果你想從工廠函數中移除參數,請在你的 struct 中定義一個輔助方法,并且讓用戶在需要時設置其屬性:

 

  1. type Library struct {    Client *http.Client}func (l *Library) getClient() *http.Client {    if l.Client == nil {        return http.DefaultClient    }    return l.Client} 

另外,如果一些全局的特性對于每個請求來講都是必須的,人們經常感覺到需要用他們自己的實例來替換 http.Client。這是一個錯誤的方法 — 如果你需要在你的請求中設置一些額外的 headers,或者在你的客戶端引入某類公共的特性,你只需要簡單為每個請求進行設置或者用組裝定制客戶端的方式來代替完全替換它。

不要引入全局變量

另一個反面模式是允許用戶在一個庫中設置全局變量。舉個例子,在你的庫中允許用戶設置一個全局的 http.Client 并被所有的 HTTP 調用執行:

 

  1. var libraryClient *http.Client = http.DefaultClientfunc SetHttpClient(client *http.Client) {    libraryClient = client} 

通常在一個庫中不應該存在一堆全局變量。當你寫代碼的時候,你應該想想用戶在他們的程序中多次使用你的這個庫會發生什么。全局變量會使不同的參數沒有辦法被使用。而且,在你的代碼中引入全局變量會引起測試上的問題并造成代碼上不必要的復雜度。使用全局變量可能會導致在你程序的不同模塊有不必要的依賴。在寫你的庫的時候,避免全局狀態是格外重要的。

返回 structs,而不是 interfaces

這是一個普遍的問題(實際上我在這一點上也犯過錯)。很多庫都有下面這類函數:

 

  1. func New() LibraryInterface {    ...} 

在上面的 case 中,返回一個 interface 使 struct 的特性在庫里被隱藏了。實際上應該這么寫:

 

  1. func New() *LibraryStruct { ...} 

在庫里不應該存在接口的聲明,除非它被用在某個函數參數中。如果出現上面的 case,你就應該想想你在寫這個庫的時候的約定。當返回一個 interface 時,你基本上得聲明一系列可用的方法。如果有人想用這個接口來實現他們自己的功能(比如說為了測試),他得打亂他們的代碼來添加更多的方法。這意味著盡管在 struct 里添加方法是安全的,但在 interface 里不是。這個想法在這篇文章中被總結得很好《Accept Interfaces Return Struct in Go[2]》。這個方案也能解決配置的問題。你想修改庫中的一些特性,你可以簡單的修改 struct 中一些公開的字段。但是如果你的庫只提供給用戶一個 interface,這就玩不轉了。

使用配置結構體來避免修改你的APIs

另一種配置方法是在你的工廠函數中接收一個配置結構體,而不是直接傳配置參數。你可以很隨意的添加新的參數而不用破壞現有的 API。你只需要做一件事情,在Config結構體中添加一個新的字段,并且確保不會影響它原本的特性。

 

  1. func New(config Config) *LibraryStruct {    ...} 

下面是一種添加結構體字段的正確的場景,如果一個用戶初始化結構體的時候忘了添加字段名,這是一種我認為修改他們的代碼能得到原諒的場景。為了維護兼容性,你應該在你的代碼中用 person{name: "Alice", age: 30} 而不是 person{"Alice", 30}。

你能在 golang.org/x/crypto[4] 包里看到對上面的補充。總之,對配置來說,我認為允許用戶在返回的結構體里設置不同的參數是一個更好的方法,并且只在編寫復雜方法時才使用這種特定方法。

總結

根據經驗來講,在寫一個庫的時候,你應該總是允許用戶指定他們自己的 http.Client來執行 HTTP 調用。而且考慮到未來迭代修改帶來的影響,你可以嘗試用可擴展的方式編寫代碼。避免全局變量,庫不能存儲全局狀態。如果你有任何疑問-參考標準庫是怎么寫的。

我認為有一個很好的想法,在你的程序中用你的庫來測試并問自己一些問題:

  • 如果你嘗試多次引入庫會發生什么?
  • 你的庫有沒有單元測試?
  • 在不破壞原有代碼的前提下,有沒有一種非侵入式的方式來擴展你的庫?
  • 在不破壞原有代碼的前提下,是否可以添加額外配置參數?

 

責任編輯:華軒 來源: 今日頭條
相關推薦

2020-02-11 09:41:02

Go語言程序員文章

2021-03-01 21:59:25

編程語言GoCX

2021-03-01 18:35:18

Go語言虛擬機

2023-04-02 23:13:07

Go語言bufio

2024-08-22 08:50:51

2025-02-11 09:01:57

2022-10-17 09:08:01

2011-02-25 10:12:09

GoWeb

2014-02-18 11:24:07

云計算PaaS

2023-06-07 17:46:32

AI高考

2023-02-13 00:24:37

Go語言日志庫

2024-05-07 08:46:06

GoGoogle云原生

2016-09-27 21:25:08

Go語言Ken Thompso

2021-02-03 20:20:34

ReacHook數據

2014-01-14 09:10:53

GoHTTP內存泄漏

2022-10-21 09:23:31

腦累計算深度學習

2021-10-18 10:53:26

Go 代碼技術

2019-07-19 15:42:57

Hadoop大數據YuniKorn

2023-06-30 08:23:36

Spring!SolonJavalin

2010-03-26 13:15:28

Python嵌入c
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 福利网址| 午夜视频网站 | 大陆一级毛片免费视频观看 | 一区二区国产精品 | 日韩福利在线 | 涩涩操 | 欧美激情精品久久久久久 | 在线日韩在线 | 欧美日本亚洲 | 毛片99 | 免费污视频 | heyzo在线| 综合激情网 | 国产一区二区中文字幕 | 欧美日韩毛片 | 日韩在线免费电影 | 香蕉久久网 | 日韩欧美网| 国产精品视频网 | 毛片网络 | 精品福利一区二区三区 | 日韩一区二区久久 | 日本精品一区 | 欧美视频在线播放 | 国产欧美一区二区三区日本久久久 | 少妇av片 | 国产成人精品一区二区三区网站观看 | 亚洲欧美一区二区三区国产精品 | 欧美又大粗又爽又黄大片视频 | 欧美综合在线视频 | 日本一区二区高清视频 | 日韩av在线不卡 | 日本字幕在线观看 | 日韩在线播放网址 | 亚洲视频中文字幕 | 日韩视频在线播放 | 国产毛片在线看 | 国产精品免费一区二区三区四区 | 精品成人佐山爱一区二区 | 国产精品美女久久久 | 国产一区二区三区免费观看在线 |