本文旨在提供一個切實的指導,在 Go 語言中實現最佳實踐和設計模式。這些編程技巧能夠幫助開發者編寫出較好的代碼。golang
爲了讓你們對這些編程技巧有更加深入的認識,我在討論這些最佳實踐的時候會附加一些示例代碼。web
那些編寫了許多優秀代碼的大師們,一直在使用一些 Go 語言編程實踐或者說是編程技巧。編程
下面列出了其中一些最好的編程實踐,可使寫出的代碼簡單、易懂而且易於維護設計模式
一、使用 gofmtbash
二、經過首先處理錯誤來避免代碼嵌套websocket
三、錯誤字符串socket
四、錯誤處理函數
五、儘可能避免代碼重複測試
六、變量名聲明ui
七、用類型選擇語句來處理特例
八、在類型選擇語句中聲明變量
九、重要的代碼要放在源文件的前面
十、點導入
十一、註釋代碼
十二、註釋語句規範
對源代碼執行 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