您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“Go編碼規范有哪些”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Go編碼規范有哪些”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
代碼必須用 gofmt 進行格式化,goland 可以配置,可以自行搜索一下配置
我們編寫的代碼每行應該不超過 120 個字符,超出部分用換行解決。
單個文件最大行數最大不超過 800 行.
單個函數最大行數不超過 80 行。
import 規范
不要使用相對路徑引入包,例如 import ../util/net
在導入包時,多個相同包名沖突時,必須使用導入別名
// bad "github.com/google/uuid" // good uuid "github.com/google/uuid"
導入的包建議分組,引用匿名包建議用一個新的分組,并加上注釋方便后面小伙伴閱讀
import ( // Go 標準庫 "fmt" //第三方包 "github.com/jinzhu/gorm" "github.com/google/uuid" "github.com/go-redis/redis/v8" // 匿名包 /import mysql driver _"github.com/jinzhu/gorm/dialects/mysql" // 內部包 slice "xxx.local/pkg/v1/goslice" meta "xxx.local/pkg/v1/meta" gomap "xxx.local/pkg/v2/gomap")
一個函數需要使用多個變量時,可以在函數最開頭處使用 var 聲明。在函數外部聲明的變量不能使用 :=
var ( port = 8081 metricServerPort = 2001)
在初始化結構體用 &struct 代替 new(struct),確保與結構體初始化一致,初始化結構體時換行。
// bad stu := new(S) stu.Name = "張三" // good stu := &S{ Name:"李四" }
使用 make 在聲明 map、array 等應該指定容器的容量,從而達到預先分配內容。
users := make(map[int]string, 10)tags := make([]int, 0, 10)
使用標準 var 關鍵字事,不要指定類型,除非它與表達式的類型不同。
// bad var _f string F() func F() string { return "hello world!" } // good var _f F() func F() string { return "hello world!" }
若函數返回 error, 必須對 error 進行處理,如果業務允許可以用 _ 接受忽略。對應 defer 可以不用顯式進行處理。
// bad func InitConfig() error { ... } InitConfig() // good func InitConfig() error { ... } err := InitConfig() if err != nil { ... } // or _ := InitConfig()
error 作為返回值時必須作為最后一個參數返回
// bad func InitConfig() (error,int) { ... } // good func InitConfig() (int, error) { ... }
錯誤需要單獨處理,盡量不要與其他的邏輯耦合在一起。
// bad res, err := InitConfig() if err != nil || res != nil { return err } // good res, err := InitConfig() if err != nil { return err } if res != nil { return fmt.Errorf("invalid result") }
業務代碼中禁止拋出 panic 錯誤。
panic 只允許出現在在服務啟動之前,如讀取配置、鏈接存儲(redis、mysql 等)。
業務代碼中建議用 error 而不是 panic 來傳遞。
每個重要的函數都要編寫測試用例,合并代碼要自動化運行一下所有的 test。
文件命名 xxx_test.go。
函數命名建議使用 Test函數名。
在每個語言中,命名規范在代碼規范中非常重要,一個統一的、精確的命名不僅僅可以提高代碼的可讀性,也可以讓人覺的這個同志真的會呀。牛!
包名必須與目錄名一致(這和其他 php、Java 還是有一點不太一樣的),盡量采取有意義、簡短的包名,不要與 go 的標準庫名稱一樣。
包名小寫,沒有下劃線,可以使用中劃線隔開,使用多級目錄來劃分目錄。
包名不要出現復數命名。
包名命名盡量簡單一目了然,ge:user、log。
文件名要見名思義,盡量簡而短
文件名小寫,組合詞用下劃線分割
與 php、Java 一樣,必須遵循駝峰規范,Go 語言中需要根據訪問的控制決定大駝峰還是小駝峰。
單元測試的函數用大駝峰,TestFunc。
與 php、Java 一樣,必須遵循駝峰規范,Go 語言中需要根據訪問的控制決定大駝峰還是小駝峰。
避免使用 info 、data 這種無意義的名稱。
命名使用名詞而非動詞。
結構體在聲明和初始化的時候需要換行,eg:
type Student struct{ Name string Age uint8}student := Student{ Name: "張三", Age: 18,}
和 php、Java 一樣,必須遵循駝峰規范,Go 語言中需要根據訪問的控制決定大駝峰還是小駝峰。
若變量為私有時,可以使用小寫命名。
局部變量可以簡寫,eg:i 表示 index。
若變量代表 bool 值,則可以使用 Is 、Can、Has 前綴命名,eg:
var isExit boolvar canReturn bool
必須遵循駝峰規范,Go 語言中需要根據訪問的控制決定大駝峰還是小駝峰。
若代表枚舉值,需要先創建。
type Code intconst ( ErrNotFound Code = iota ErrFatal)
好像學過的語言中,都是從字符串開始說起的。就像寫代碼第一行都是從 Hello World!一樣!同意的點贊哈。
字符串判空值
// bad if s == "" { ...} // good if len(s) == 0 { ...}
字符串去除前后子串。
// bad var s1 "hello world"var s2 "hello"var s3 strings.TrimPrefix(s1, s2) // good var s1 "hello world"var s2 "hello"var s3 stringif strings.HasPrefix(s1, s2){ s3 = s1[len(s2):]}
聲明 slice。
// bad s := []string{}s := make([]string, 10) // good var s []string s := make([]string, 0, 10)
非空判斷。
//bad if len(slice) >0 { ...} // good if slice != nil && len(slice) > 0 { ...}
slice copy。
// badvar b1,b2 []bytefor i, v := range b1 { b2[i] = v}for i := range b1 { b2[i] = b1[i]}// goodcopy(b2,b1)
slice 新增。
// bad var a,b []intfor _, v := range a { b = append(b,v)} // good var a, b []int b := append(b, a...)
初始化需要多行。
type Student struct{ Name string Age uint8}student := Student{ Name: "張三", Age: 18,}
if 可以用局部變量的方式初始化。
if err := InitConfig; err != nil { return err}
不允許在 for 中使用 defer, defer 只在函數結束時才會執行。
// bad for file := range files { fd, err := os.Open(file) if err != nil { return err } defer fd.close()} // good for file := range files{ func() { fd,err := os.open(file) if err!=nil { return err } defer fd.close() }()}
如果不需要 key 直接用 _ 忽略,value 也一樣。
for _, v := range students { ...}for i, _ := range students { ...}for i, v := range students { ...}
注: 若操作指針時請注意不能直接用 s := v。想知道可以評論區告訴我哦!
和其他語言不一樣,必須要有 defalt
switch type { case 1: fmt.Println("type = 1") break case 2: fmt.Println("type = 2") break default : fmt.Println("unKnown type")}
業務中不允許使用 goto。
框架和公共工具也不允許使用 goto。
傳參和返回的變量小寫字母。
傳入參數時slice、map、interface、chan 禁止傳遞指針類型。
采用值傳遞,不用指針傳值。
入參個數不能超出 5 個,超過的可以用 struct 傳值。
返回值超出 1 個時,需要用變量名返回。
多個返回值可以用 struct 傳。
當操作資源、或者事物需要提交回滾時,可以在創建開始下方就使用 defer 釋放資源。
創建資源后判斷 error,非 error 情況后在用 defer 釋放。
為了代碼可讀性,為了世界和平,盡量別用太多的嵌套,因為真的很難有人類能看懂。
能不用全局變量就不用,可以用參數傳值的方式,這樣可以大大降低耦合,更有利于單元測試。
衣服開發中,在函數間多用 context 傳遞上下文,在請求開始時可以生成一個 request_id,便于鏈路、日志追蹤。
在業務開發中,盡量使用 strconv 來替代 fmt。
我們在使用 string 字符串類型時,當修改的場景較多,盡量在使用時用 []byte 來替代。因為每次對 string 的修改都需要重新在申請內存。
append 要小心自動擴容的情況,最好在申明時分配好容量,避免擴容所帶來的性能上的損耗以及分配新的內存地址。若不能確定容量,應選擇一個比較大一點的值。
并發場景下,map 非線程安全,需要加鎖。還有一種評論區告訴我吧。
interface 在編譯期間無法被檢查,使用上會出現 panic,需要注意
讀到這里,這篇“Go編碼規范有哪些”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。