Uber 把公司內部的《Go 語言風格指南》開源了
Uber 近日開放了其公司內部使用的《Go 語言風格指南》。
根據Uber的介紹,《Go 語言風格指南》是支配Uber代碼的慣例,這些慣例不僅涵蓋源文件格式,而且由gofmt代替處理。(gofmt工具可以幫助開發者格式化他們的代碼到統一的風格。)
本指南通過詳細介紹了Uber在編寫Go代碼時的注意事項,從而使代碼庫更加易于管理,幫助開發者們更好的使用Go的語言特性
該指南最初由Prashant Varanasi和Simon Newton編寫,目的是使一些同事快速使用Go。多年來,已根據其他人的反饋進行了多次的修改。
其中許多約定是 Go 的通用準則,而其它準則則參考了外部資源:
- Effective Go
- The Go common mistakes guide
所用的代碼在運行 golint 和 go vet 之后不會有報錯。建議將編輯器設置為:
- 保存時運行 goimports
- 運行 golint 和 go vet 來檢查錯誤
下面以接口和指針為例
你幾乎不需要指向接口的指針,你應該把接口當作值傳遞,它的基礎數據仍然可以當成一個指針。
一個接口是兩個字段:
1、指向特定類型信息的指針。你可以認為這是 "type."。
2、數據指針,如果存儲的數據是指針,則直接存儲。如果數據存儲的是值,則存儲指向此值的指針。
如果要接口方法修改基礎數據,則必須使用指針。
接收器和接口
具有值接收器的方法可以被指針和值調用。例如:
- type S struct {
- data string
- }
- func (s S) Read() string {
- return s.data
- }
- func (s *S) Write(str string) {
- s.data = str
- }
- sVals := map[int]S{1: {"A"}}
- // You can only call Read using a value
- sVals[1].Read()
- // This will not compile:
- // sVals[1].Write("test")
- sPtrs := map[int]*S{1: {"A"}}
- // You can call both Read and Write using a pointer
- sPtrs[1].Read()
- sPtrs[1].Write("test")
同樣,即使該方法具有值接收器,也可以通過指針來滿足接口。
- type F interface {
- f()
- }
- type S1 struct{}
- func (s S1) f() {}
- type S2 struct{}
- func (s *S2) f() {}
- s1Val := S1{}
- s1Ptr := &S1{}
- s2Val := S2{}
- s2Ptr := &S2{}
- var i F
- i = s1Val
- i = s1Ptr
- i = s2Ptr
- // The following doesn't compile, since s2Val is a value, and there is no value receiver for f.
Effective Go對Pointers vs. Values分析的不錯
目前,guide在Github上標星2.9K,獲得246個Fork(Github地址:https://github.com/uber-go/guide/blob/master/style.md)