Golang編碼規范指南


格式化規范代碼格式化

go默認已經有了gofmt工具,但是我們強烈建議使用goimport工具,這個在gofmt的基礎上增加了自動刪除和引入包.

go get golang.org/x/tools/cmd/goimports

 

 

 

行長約定

一行最長不超過80個字符,超過的請使用換行展示,盡量保持格式優雅。

go vet

vet工具可以幫我們靜態分析我們的源碼存在的各種問題,例如多余的代碼,提前return的邏輯,struct的tag是否符合標准等。

go get golang.org/x/tools/cmd/vet

使用如下:

go vet .

package名字 (包命名)

保持package的名字和目錄保持一致,盡量采取有意義的包名,簡短,有意義,盡量和標准庫不要沖突。包名應該為小寫單詞,不要使用下划線或者混合大小寫。

文件命名

不要使用下划線或者混合大小寫 盡量采取有意義的文件名,簡短,有意義,應該為小寫單詞,使用下划線分隔各個單詞。非單元測試文件不要以_test結尾,go編譯器默認x_test.go為單元測試文件,不會進行編譯。

import 規范

import在多行的情況下,goimports會自動幫你格式化,但是我們這里還是規范一下import的一些規范,如果你在一個文件里面引入了一個package,還是建議采用如下格式:

import (

    "fmt")

如果你的包引入了三種類型的包,標准庫包,程序內部包,第三方包,建議采用如下方式進行組織你的包:

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”

變量申明

變量名采用駝峰標准,不要使用_來命名變量名,多個變量申明放在一起,通過首字母大小寫來控制是否包外可見

var (

    Found bool

    count int)

在函數外部申明必須使用var,不要采用:=,容易踩到變量的作用域的問題。

接口命名

單個函數的接口名以"er"作為后綴,例如type Reader interface {…}

兩個函數的接口名綜合兩個函數名,例如type WriteFlusher interface {…}

三個以上函數的接口名,類似於結構體名,例如type Car interface {…}

特殊名詞的首字母縮寫需要按照規范來,例如URLProxy或者urlProxy不要命名為UrlProxy。

 

自定義類型的string循環問題

如果自定義的類型定義了String方法,那么在打印的時候會產生隱藏的一些bug

type MyInt int

func (m MyInt) String() string {

    return fmt.Sprint(m)   //BUG:死循環}

 

func(m MyInt) String() string {

    return fmt.Sprint(int(m))   //這是安全的,因為我們內部進行了類型轉換}

避免返回命名的參數

如果你的函數很短小,少於10行代碼,那么可以使用,不然請直接使用類型,因為如果使用命名變量很
容易引起隱藏的bug

func Foo(a int, b int) (string, ok){

}

當然如果是有多個相同類型的參數返回,那么命名參數可能更清晰:

func (f *Foo) Location() (float64, float64, error)

下面的代碼就更清晰了:

// Location returns f's latitude and longitude.// Negative values mean south and west, respectively.

func (f *Foo) Location() (lat, long float64, err error)

錯誤處理

錯誤處理的原則就是不能丟棄任何有返回err的調用,不要采用_丟棄,必須全部處理。接收到錯誤,要么返回err,要么實在不行就panic,或者使用log記錄下來

error 信息

error的信息不要采用大寫字母,盡量保持你的錯誤簡短,但是要足夠表達你的錯誤的意思。

長句子打印或者調用,使用參數進行格式化分行

我們在調用fmt.Sprint或者log.Sprint之類的函數時,有時候會遇到很長的句子,我們需要在參數調用處進行多行分割:

下面是錯誤的方式:

log.Printf(“A long format string: %s %d %d %s”, myStringParameter, len(a),

    expected.Size, defrobnicate(“Anotherlongstringparameter”,

        expected.Growth.Nanoseconds() /1e6))

應該是如下的方式:

log.Printf(

    “A long format string: %s %d %d %s”,

    myStringParameter,

    len(a),

    expected.Size,

    defrobnicate(

        “Anotherlongstringparameter”,

        expected.Growth.Nanoseconds()/1e6,

    ),)   

注意閉包的調用

在循環中調用函數或者goroutine方法,一定要采用顯示的變量調用,不要再閉包函數里面調用循環的參數

fori:=0;i<limit;i++{

    go func(){ DoSomething(i) }() //錯誤的做法

    go func(i int){ DoSomething(i) }(i)//正確的做法}

http://golang.org/doc/articles/race_detector.html#Race_on_loop_counter

在邏輯處理中禁用panic

main包中只有當實在不可運行的情況采用panic,例如文件無法打開,數據庫無法連接導致程序無法
正常運行,但是對於其他的package對外的接口不能有panic,只能在包內采用。

強烈建議在main包中使用log.Fatal來記錄錯誤,這樣就可以由log來結束程序。

注釋規范

注釋可以幫我們很好的完成文檔的工作,寫得好的注釋可以方便我們以后的維護。詳細的如何寫注釋可以
參考:http://golang.org/doc/effective_go.html#commentary

bug注釋

針對代碼中出現的bug,可以采用如下教程使用特殊的注釋,在godocs可以做到注釋高亮:

// BUG(astaxie):This divides by zero. var i float = 1/0

http://blog.golang.org/2011/03/godocdocumentinggocode.html

struct規范

struct申明和初始化格式采用多行:

定義如下:

type User struct{

    Username  string

    Email     string}

初始化如下:

u := User{

    Username: "astaxie",

    Email:    "astaxie@gmail.com",}

recieved是值類型還是指針類型

到底是采用值類型還是指針類型主要參考如下原則:

func(w Win) Tally(playerPlayer)int    //w不會有任何改變

func(w *Win) Tally(playerPlayer)int    //w會改變數據

更多的請參考:https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Receiver_Type

mutex的struct必須是指針receivers

其他

如果你定義的struct中帶有mutex,那么你的receivers必須是指針

1、receiver命名最多2個字母,不能使用me或者self或者this,例如func (c *Client) GetUserName() string

2、每行代碼長度最好不超過80個字符,如果超過建議換行

3、函數返回值采用返回"指針"類型而不是返回"值"類型 (推薦但不強制)

4、錯誤處理的原則是不能忽略任何error,不要使用"_"丟棄,必須全部處理。接收到錯誤,要么返回error給上層調用,要么使用log打印對應的error和warn信息 (強制)

5、沒十分必要不能panic,進程開始的處理函數可以panic

6、任何一個goroutine都應該有recover來保護程序不會因為panic而crash,因為任何一個goroutine如果拋panic但沒有recover整個程序會crash

7、注意閉包的使用,在循環中調用函數或者goroutine方法,一定要采用顯示的變量調用,不要再閉包函數里面調用循環的參數


Word文檔下載
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM