引言
Go
語言是從既有的語言中借鑒了許多理念,但其與眾不同的特性, 使得使用 Go
編程在本質上就不同于其它語言。將現有的 C++
或 Java
程序直譯為 Go
程序并不能令人滿意 —— 畢竟 Java
程序是用 Java
編寫的,而不是 Go
。 另一方面,若從 Go
的角度去分析問題,你就能編寫出同樣可行但大不相同的程序。 換句話說,要想將 Go
程序寫得好,就必須理解其特性和風格。了解命名、格式化、 程序結構等既定規則也同樣重要,這樣你編寫的程序才能更容易被其他程序員所理解。
本文主要摘錄了日常開發過程中,會遇到的一些需要注意的事項,若想閱讀原文,請參考文末鏈接。
命名與格式
對于格式化而言,Go
默認已經有了 gofmt
工具,我們可以使用其對編寫的代碼按照標準風格縮進、對齊等。同時,在編碼的時候,一些命名規范也需要注意,避免出現一些隱藏的bug。
在 vscode
中可以使用快捷鍵:alt+shift+F
(shift+option+F
)直接使用(CoLand
則為ctrl+alt+L
)。還有 goimport
和 go vet
工具對應自動刪除和引入包,以及靜態分析代碼是否符合標準。
// 獲取方式
go get golang.org/x/tools/cmd/goimports
go get golang.org/x/tools/cmd/vet
-
包及格式
包應當以小寫的單個單詞來命名,且不應使用下劃線或駝峰記法
還有一點,就是自建包的函數命名也需遵循簡潔明了的準則,如
bufio.Reader
而非bufio.BufReader
。once.Do
表述足夠清晰, 使用once.DoOrWaitUntilDone(setup)
就有點畫蛇添足包的import規范:應當按:標準庫,項目包,第三方包的順序組織在import中,中間采用空行隔開:
import ( "encoding/json" "strings" "myproject/models" "myproject/controller" "myproject/utils" "github.com/astaxie/beego" "github.com/go-sql-driver/mysql" )
- 同時,在項目中不要使用相對路徑來引入包:
// 這是不好的導入 import “../net” // 這是正確的做法 import “github.com/repo/proj/src/net”
-
變量命名
約定采用駝峰法命名參數,如
MixedCaps
或mixedCaps
而不是下劃線,首字母根據訪問控制原則大寫或者小寫多個變量申明最好放在一起,如:
var ( Found bool count int )
在函數外部申明必須使用var,不要采用
:=
,容易踩到變量的作用域的坑-
注意特有名詞的使用:
- 如果變量為私有,且特有名詞為首個單詞,則使用小寫,如
apiClient
- 其它情況都應當使用該名詞原有的寫法,如
APIClient
- 若變量類型為 bool 類型,則名稱應以
Has
,Is
,Can
或Allow
開頭
- 如果變量為私有,且特有名詞為首個單詞,則使用小寫,如
-
常量均需使用全部大寫字母組成,并使用下劃線分詞
const APP_VER = "1.0"
-
文件命名
- 盡量采取有意義的文件名,簡短,有意義,應該為**小寫**單詞,使用**下劃線**分隔各個單詞。
-
結構體命名
- 采用駝峰命名法,首字母根據訪問控制大寫或者小寫
-
縮進與行長
- 使用制表符(tab)縮進,
gofmt
默認也使用它,在你認為確實有必要時再使用空格 - Go 對行的長度沒有限制,但是建議不要超過80個字符,超過的請使用換行展示,盡量保持格式優雅
- 使用制表符(tab)縮進,
代碼注釋
Go提供C風格的 /* */
塊注釋和 C++
風格的 //
行注釋。行注釋是常態;塊注釋主要顯示為包注釋,但在表達式中很有用或禁用大量代碼。
-
包注釋
-
每個包都應該有一個包注釋,包注釋應該包含下面基本信息:
包的基本簡介(包名,簡介) 創建者,格式: 創建人: rtx 名 創建時間,格式:創建時間: yyyyMMdd 如: // util 包, 該包包含了項目共用的一些常量,封裝了項目中一些共用函數。 // 創建人: hope // 創建時間: 20221116
-
-
結構(接口)及函數(方法)注釋
-
結構體或者函數最好都有對應的注釋說明,說明的格式其實和其他語言是大致一樣的,這里建議是包含以下幾個部分:簡要說明、參數列表、返回值。此項不做強制要求,但至少需要有一行簡要說明
// NewtAttrModel , 屬性數據層操作類的工廠方法 // 參數: // ctx : 上下文信息 // 返回值: // 屬性操作類指針 func NewAttrModel(ctx *common.Context) *AttrModel { }
-
-
代碼邏輯注釋及風格
對于一些關鍵位置的代碼邏輯,或者局部較為復雜的邏輯,需要有相應的邏輯說明
-
統一使用中文注釋,對于中英文字符之間嚴格使用空格分隔,同時注釋長度也不宜過長
// 從 Redis 中批量讀取屬性,對于沒有讀取到的 id , 記錄到一個數組里面,準備從 DB 中讀取
錯誤
錯誤處理的原則就是不能丟棄任何有返回err的調用,不要使用
_
丟棄,必須全部處理。接收到錯誤,要么返回err
,或者使用log
記錄下來盡早
return
,而不是一味地使用else
,一旦有錯誤發生,馬上返回盡量不要使用
panic
,除非你知道你在做什么,錯誤描述如果是英文必須為小寫,不需要標點結尾
-
采用獨立的錯誤流進行處理
// 錯誤寫法 if err != nil { // error handling } else { // normal code } // 正確寫法 if err != nil { // error handling return // or continue, etc. }
其他
打開文件或者其他資源時,要注意記得釋放,最常用的就是使用
defer
Go 還有許多特性,切片、映射、打印、追加,這里不一一贅述,有興趣可以自行學習一下,靈活使用這些特性可以極大的提高編碼效率以及代碼可讀性
參考資料:Effective Go