1蔚袍、使用 gofmt
2、通過首先處理錯(cuò)誤來避免代碼嵌套
3配名、錯(cuò)誤字符串
4啤咽、錯(cuò)誤處理
5、盡量避免代碼重復(fù)
6渠脉、變量名聲明
7宇整、用類型選擇語句來處理特例
8、在類型選擇語句中聲明變量
9芋膘、重要的代碼要放在源文件的前面
10鳞青、點(diǎn)導(dǎo)入
11、注釋代碼
12为朋、注釋語句規(guī)范
對源代碼執(zhí)行 gofmt 命令,會(huì)自動(dòng)修正大部分粗心導(dǎo)致的問題潜腻。幾乎全世界的 Go 語言開發(fā)者都在用 gofmt。
gofmt 首先讀取源代碼器仗,然后輸出經(jīng)過縮進(jìn)融涣、垂直對齊甚至規(guī)范注釋后的代碼。
gofmt 文件名 - 輸出格式化后的代碼
gofmt -w 文件名 - 重新格式化代碼并更新文件
gofmt -r'rule' 文件名 - 格式化代碼前執(zhí)行指定的規(guī)則
gofmt 包所在的路徑 - 格式化整個(gè)包下的源文件
文件名:demo.go
packagemain
import"fmt"
// this is demo to format code
// with gofmt command
varaint=10;
varbint=15;
varcstring="Welcome to Agira";
funcprint(){
fmt.Println("Value for a,b and c is : ");
? ? ? ? ? ? ? ? ? ? ? fmt.Println(a);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fmt.Println((b));
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fmt.Println(c);
? ? ? ? ? ? ? ? ? ? ? ? }
輸入命令:$ gofmt demo.go
輸出結(jié)果:
packagemain
import"fmt"
// this is demo to format code
// with gofmt command
varaint=10
varbint=15
varcstring=? “Welcome to Agira”
funcprint(){
fmt.Println("Value for a,b and c is : ")
? ? ? fmt.Println(a)
? ? ? fmt.Println((b))
? ? ? fmt.Println(c)
}
避免使用多重條件或者嵌套條件威鹿,當(dāng)我們處理后面的代碼前需要處理錯(cuò)誤,例如下面的代碼
err := request()
iferr !=nil{
// handling error
}else{
// normal code
}
我們可以用下面的方式代替
err := request()
iferr !=nil{
// handling error
return// or continue, etc.
}
// proceed to further
嵌套條件語句越少轨香,讀者越容易理解
如果 if 語句中包含初始化語句忽你,例如:
ifx, err := f(); err !=nil{
// handling error
return
}else{
// use x
}
我們應(yīng)該在代碼中定義一個(gè)短變量,在之后的 if 語句中使用這個(gè)變量
x, err := f()
iferr !=nil{
// handling error
return
}
// use x
錯(cuò)誤字符串首字母不應(yīng)該大寫(除非是以一些特殊的名詞或者縮寫開頭)科雳。
例如:
fmt.Errorf("Something went wrong") 應(yīng)該寫成 fmt.Errorf("something went wrong")
不要用 _ 來忽略錯(cuò)誤。如果一個(gè)函數(shù)可能返回錯(cuò)誤信息糟秘,檢查函數(shù)的返回值 简逮,確認(rèn)函數(shù)是否執(zhí)行成功了。更好的做法是處理這個(gè)錯(cuò)誤并返回尿赚,不然的話如果出現(xiàn)任何異常程序會(huì)產(chǎn)生一個(gè) panic 錯(cuò)誤
不要在正常處理流程中使用 panic, 那種情況下可以用 error 和多重返回值散庶。
如果你想在控制模塊和數(shù)據(jù)模塊使用同一個(gè)類型結(jié)構(gòu)凌净,創(chuàng)建一個(gè)公共文件悲龟,在那里聲明這個(gè)類型
在 Go 編程中最好用短的變量名冰寻,尤其是那些作用域比較有限的局部變量
用c而不是lineCount
用i而不是sliceIndex
1须教、基本規(guī)則:距離聲明的地方越遠(yuǎn),變量名需要越具可讀性性雄。
2没卸、作為一個(gè)函數(shù)接收者,1秒旋、2 個(gè)字母的變量比較高效约计。
3、像循環(huán)指示變量和輸入流變量迁筛,用一個(gè)單字母就可以煤蚌。
4、越不常用的變量和公共變量细卧,需要用更具說明性的名字尉桩。
如果你不確定 iterface{} 是什么類型贪庙,就可以用類型選擇語句
例如:
funcWrite(vinterface{}){
switchv.(type) {
casestring:
s := v.(string)
? fmt.Printf(“%T\n”,s)
caseint:
i := v.(int)
? fmt.Printf(“%T\n”,i)
}
}
在類型選擇語句中聲明的變量,在每個(gè)分支中會(huì)自動(dòng)轉(zhuǎn)化成正確的類型
例如:
funcWrite(vinterface{}){
switchx := v.(type) {
casestring:
? fmt.Printf(“%T\n”,x)
caseint:
? fmt.Printf(“%T\n”,x)
}
}
如果你有像版權(quán)聲明这橙、構(gòu)建標(biāo)簽、包注釋這樣的重要信息导披,盡量寫在源文件的靠前位置屈扎。 我們可以用空行把導(dǎo)入語句分成若干個(gè)組,標(biāo)準(zhǔn)庫放在最前面撩匕。
import(
"fmt"
"io"
"log"
"golang.org/x/net/websocket"
)
在接下來的代碼中鹰晨,首先寫重要的類型,在最后寫一些輔助型的函數(shù)和類型。
點(diǎn)導(dǎo)入可以測試循環(huán)依賴漠趁。并且它不會(huì)成為被測試代碼的一部分:
packagefoo_test
import(
"bar/testutil"http:// also imports "foo"
."foo"
)
這樣的情況下,測試代碼不能放在 foo 包中哩牍,因?yàn)樗肓?bar/testutil包棚潦,而它導(dǎo)入了 foo。所以我們用點(diǎn)導(dǎo)入
的形式讓文件假裝是包的一部分膝昆,而實(shí)際上它并不是丸边。除了這個(gè)使用情形外,最好不要用點(diǎn)導(dǎo)入荚孵。因?yàn)樗鼤?huì)讓讀者閱讀代碼時(shí)更加困難妹窖,因?yàn)楹茈y確定像 Quux
這樣的名字是當(dāng)前包的頂層聲明還是引入的包。
在包名字之前添加包相關(guān)的注釋
// Package playground registers an HTTP handler at “/compile” that
// proxies requests to the golang.org playground service.
packageplayground
出現(xiàn)在 godoc 中的標(biāo)識(shí)符骄呼,需要適當(dāng)?shù)淖⑨?/p>
// Author represents the person who wrote and/or is presenting the document.
typeAuthorstruct{
? Elem []Elem
}
// TextElem returns the first text elements of the author details.
// This is used to display the author’ name, job title, and company
// without the contact details.
func(p *Author)TextElem()(elems []Elem){
即使注釋語句看上去有一些冗余判没,也需要是一個(gè)完整的句子蜓萄,。這樣會(huì)讓它們在 godoc 中有更的格式化效果澄峰。注釋需要以被注釋的名字開頭嫉沽,以點(diǎn)號(hào)結(jié)尾。
// Request represents a request to run a command.
typeRequeststruct{ …
// Encode writes the JSON encoding of req to w.
funcEncode(w io.Writer, req *Request){ … and so on.