本文旨在提供一個切實的指導,在 Go 語言中實現最佳實踐和設計模式。這些編程技巧能夠幫助開發者編寫出較好的代碼。golang
爲了讓你們對這些編程技巧有更加深入的認識,我在討論這些最佳實踐的時候會附加一些示例代碼。web
那些編寫了許多優秀代碼的大師們,一直在使用一些 Go 語言編程實踐或者說是編程技巧。編程
下面列出了其中一些最好的編程實踐,可使寫出的代碼簡單、易懂而且易於維護設計模式
一、使用 gofmtwebsocket
二、經過首先處理錯誤來避免代碼嵌套socket
三、錯誤字符串函數
四、錯誤處理測試
五、儘可能避免代碼重複this
六、變量名聲明設計
七、用類型選擇語句來處理特例
八、在類型選擇語句中聲明變量
九、重要的代碼要放在源文件的前面
十、點導入
十一、註釋代碼
十二、註釋語句規範
對源代碼執行 gofmt 命令,會自動修正大部分粗心致使的問題。幾乎全世界的 Go 語言開發者都在用 gofmt。
gofmt 首先讀取源代碼,而後輸出通過縮進、垂直對齊甚至規範註釋後的代碼。
gofmt 文件名 - 輸出格式化後的代碼
gofmt -w 文件名 - 從新格式化代碼並更新文件
gofmt -r'rule' 文件名 - 格式化代碼前執行指定的規則
gofmt 包所在的路徑 - 格式化整個包下的源文件
文件名:demo.go
package main import "fmt" // this is demo to format code // with gofmt command var a int=10; var b int=15; var c string= "Welcome to Agira"; func print(){ fmt.Println("Value for a,b and c is : "); fmt.Println(a); fmt.Println((b)); fmt.Println(c); }
輸入命令:$ gofmt demo.go
輸出結果:
package main import "fmt" // this is demo to format code // with gofmt command var a int = 10 var b int = 15 var c string = 「Welcome to Agira」 func print() { fmt.Println("Value for a,b and c is : ") fmt.Println(a) fmt.Println((b)) fmt.Println(c) }
避免使用多重條件或者嵌套條件,當咱們處理後面的代碼前須要處理錯誤,例以下面的代碼
err := request() if err != nil { // handling error } else { // normal code }
咱們能夠用下面的方式代替
err := request() if err != nil { // handling error return // or continue, etc. } // proceed to further
嵌套條件語句越少,讀者越容易理解
若是 if 語句中包含初始化語句,例如:
if x, err := f(); err != nil { // handling error return } else { // use x }
咱們應該在代碼中定義一個短變量,在以後的 if 語句中使用這個變量
x, err := f() if err != nil { // handling error return } // use x
錯誤字符串首字母不該該大寫(除非是以一些特殊的名詞或者縮寫開頭)。
例如:
fmt.Errorf("Something went wrong") 應該寫成 fmt.Errorf("something went wrong")
不要用 _ 來忽略錯誤。若是一個函數可能返回錯誤信息,檢查函數的返回值 ,確認函數是否執行成功了。更好的作法是處理這個錯誤並返回,否則的話若是出現任何異常程序會產生一個 panic 錯誤
不要在正常處理流程中使用 panic, 那種狀況下能夠用 error 和多重返回值。
若是你想在控制模塊和數據模塊使用同一個類型結構,建立一個公共文件,在那裏聲明這個類型
在 Go 編程中最好用短的變量名,尤爲是那些做用域比較有限的局部變量
用 c
而不是 lineCount
用 i
而不是 sliceIndex
一、基本規則:距離聲明的地方越遠,變量名須要越具可讀性。
二、做爲一個函數接收者,一、2 個字母的變量比較高效。
三、像循環指示變量和輸入流變量,用一個單字母就能夠。
四、越不經常使用的變量和公共變量,須要用更具說明性的名字。
若是你不肯定 iterface{} 是什麼類型,就能夠用類型選擇語句
例如:
func Write(v interface{}) { switch v.(type) { case string: s := v.(string) fmt.Printf(「%T\n」,s) case int: i := v.(int) fmt.Printf(「%T\n」,i) } }
在類型選擇語句中聲明的變量,在每一個分支中會自動轉化成正確的類型
例如:
func Write(v interface{}) { switch x := v.(type) { case string: fmt.Printf(「%T\n」,x) case int: fmt.Printf(「%T\n」,x) } }
若是你有像版權聲明、構建標籤、包註釋這樣的重要信息,儘可能寫在源文件的靠前位置。 咱們能夠用空行把導入語句分紅若干個組,標準庫放在最前面。
import ( "fmt" "io" "log" "golang.org/x/net/websocket" )
在接下來的代碼中,首先寫重要的類型,在最後寫一些輔助型的函數和類型。
點導入能夠測試循環依賴。而且它不會成爲被測試代碼的一部分:
package foo_test import ( "bar/testutil" // also imports "foo" . "foo" )
這樣的狀況下,測試代碼不能放在 foo 包中,由於它引入了 bar/testutil包,而它導入了 foo。因此咱們用點導入 的形式讓文件僞裝是包的一部分,而實際上它並非。除了這個使用情形外,最好不要用點導入。由於它會讓讀者閱讀代碼時更加困難,由於很難肯定像 Quux 這樣的名字是當前包的頂層聲明仍是引入的包。
在包名字以前添加包相關的註釋
// Package playground registers an HTTP handler at 「/compile」 that // proxies requests to the golang.org playground service. package playground
出如今 godoc 中的標識符,須要適當的註釋
// Author represents the person who wrote and/or is presenting the document. type Author struct { 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) {
即便註釋語句看上去有一些冗餘,也須要是一個完整的句子,。這樣會讓它們在 godoc 中有更的格式化效果。註釋須要以被註釋的名字開頭,以點號結尾。
// Request represents a request to run a command. type Request struct { … // Encode writes the JSON encoding of req to w. func Encode(w io.Writer, req *Request) { … and so on.
但願這些 Go 語言最佳實踐能夠幫助你提升代碼質量。咱們也列出了其它許多技術的最佳實踐。
via: http://www.agiratech.com/12-best-golang-agile-practices-we-must-follow/
做者:Reddy Sai 譯者:jettyhan 校對:polaris1119