1. 程式人生 > 實用技巧 >【go語言學習】程式設計規範

【go語言學習】程式設計規範

學習一門語言,首先要了解該語言的程式碼程式設計規範,以提高程式碼的可讀性、規範性。

一、 命名規範

同其他程式語言一樣,go 語言命名可以由字母、數字和下劃線組成,並且不能以數字開頭。go 語言命名區分大小寫。

當命名以大寫字母開頭時,可以被外部包的程式碼使用,以小寫字母開頭,則對外部包不可見。

兩個等級:【shall】必須 【should】建議。

1、包命名:package

【shall】包名必須全部小寫,無下劃線,簡短,見名知義。儘量不要與標準庫重名,禁止通過中劃線連線多個單詞。
【should】儘量和目錄名保持一致。

package main

package student
2、 檔案命名

【shall】檔名使用小寫單詞,可以使用下劃線分割各個單詞,但是頭尾不能為下劃線。
【should】檔名雖然允許出現下劃線,但是儘量避免。檔名儘量簡短,見名知義。

my_utils.go
3、變數命名

【shall】變數命名採用大小寫駝峰法命名,不允許使用下劃線。

  • 特有名詞開頭在私有的情況下,使用小寫,如urlArray
  • 特有名詞開頭在公開的情況下,使用小寫,如URLArray
  • 若變數型別為 bool,則命名應以HasIsCanAllow開頭,如isExit
4、常量命名

【should】常量&列舉名,大小寫駝峰法,不允許下劃線,第三方包例外。

const AppEnv = "1.0"
5、 結構體命名

【shall】結構體名必須為大小寫混排的駝峰模式,不允許出現下劃線,首字母根據訪問控制大寫或者小寫
【should】結構名建議採用名詞、動名詞,struct 申明和初始化格式採用多行,例如下面:

// 多行申明
type User struct{
    Username  string
    Email     string
}

// 多行初始化
u := User{
    Username: "astaxie",
    Email:    "[email protected]",
}

6、 介面命名

【shall】介面名必須為大小寫混排的駝峰模式,不允許出現下劃線,首字母根據訪問控制大寫或者小寫,整體必須為名詞。
【should】單個函式的結構名以 “er” 作為字尾,例如 Reader , Writer 。

type Reader interface {
        Read(p []byte) (n int, err error)
}

7、函式&方法名

【shall】函式名必須為大小寫混排的駝峰模式,首字母根據訪問控制大寫或者小寫。
【should】函式名力求精簡準確,並採用動詞或動詞短語。

func MakeRegexpArrayOrDie(){}     // 包外可訪問

func matchesRegexp(){}            // 包內訪問

【shall】方法接收者命名必須為大小寫混排,首字母小寫。方法接收者命名要能夠體現接收者物件。
【should】方法接收者命名通常1個或者2個字母就夠,最長不能超過4個字母。
【should】方法接收者命名不要使用 me,this 或者 self 這種泛指的名字。

func (c *Controller) Run(){}
8、 引數和返回值命名

【should】引數名和返回值命名必須為大小寫混排的駝峰模式,且首字母小寫,不能有下劃線。

func getAge(studentName string)(age int){}

二、註釋規範

Go 提供 C 風格的/* */塊註釋和 C++ 風格的//行註釋。行註釋更加通用;塊註釋主要用於針對包的詳細說明或者遮蔽大塊的程式碼。

1、包註釋
  • 每個包都應該有一個包註釋,一個位於 package 子句之前的塊註釋或行註釋。
  • 包註釋應該包含下面基本資訊(簡介,建立人,建立時間)

例如 util 包的註釋示例如下

// util 包, 這是一個公共函式的工具包
// 建立人: 姑姑
// 建立時間: 20200816
2、結構&介面註釋

每個自定義的結構體或者介面都應該有註釋說明,該註釋對結構進行簡要介紹,放在結構體定義的前一行,格式為: 結構體名, 結構體說明。同時結構體內的每個成員變數都要有說明,該說明放在成員變數的後面(注意對齊),例項如下:

// User , 使用者物件,定義了使用者的基礎資訊
type User struct{
    Username  string // 使用者名稱
    Email     string // 郵箱
}
3、函式(方法)註釋

每個函式或者方法都應該有註釋說明,函式的註釋應該包括三個方面(嚴格按照此順序撰寫):

  • 簡要說明,格式說明:以函式名開頭,“,”分隔說明部分
  • 引數列表:每行一個引數,引數名開頭,“,”分隔說明部分
  • 返回值: 每行一個返回值

示例如下:

// NewtAttrModel , 屬性資料層操作類的工廠方法
// 引數:
//      ctx ,上下文資訊
// 返回值:
//      屬性操作類指標
func NewAttrModel(ctx *common.Context) *AttrModel {
}
4、程式碼邏輯註釋

對於一些關鍵位置的程式碼邏輯,或者區域性較為複雜的邏輯,需要有相應的邏輯說明,方便其他開發者閱讀該段程式碼,例項如下:

// 從 Redis 中批量讀取屬性,對於沒有讀取到的 id ,
// 記錄到一個數組裡面,準備從 DB 中讀取
xxxxx
xxxxxxx
xxxxxxx
5、註釋風格

統一使用中文註釋,對於中英文字元之間嚴格使用空格分隔, 這個不僅僅是中文和英文之間,英文和中文標點之間也都要使用空格分隔,例如:

// 從 Redis 中批量讀取屬性,對於沒有讀取到的 id , 
// 記錄到一個數組裡面,準備從 DB 中讀取

上面 Redis 、 id 、 DB 和其他中文字元之間都是用了空格分隔。

  • 建議全部使用單行註釋
  • 和程式碼的規範一樣,單行註釋不要過長,禁止超過 120 字元。

三、程式碼風格

1、縮排和折行
  • 縮排直接使用 gofmt 工具格式化即可(gofmt 是使用 tab 縮排的);
  • 折行方面,一行最長不超過120個字元,超過的請使用換行展示,儘量保持格式優雅。
2、語句的結尾

Go語言中是不需要類似於Java需要冒號結尾,預設一行就是一條資料

如果你打算將多個語句寫在同一行,它們則必須使用 ;

3、括號和空格

括號和空格方面,也可以直接使用 gofmt 工具格式化(go 會強制左大括號不換行,換行會報語法錯誤),所有的運算子和運算元之間要留空格。

// 正確的方式
if a > 0 {

} 

// 錯誤的方式
if a>0  // a ,0 和 > 之間應該空格
{       // 左大括號不可以換行,會報語法錯誤

}

4、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”

但是如果是引入本專案中的其他包,最好使用相對路徑。

5、錯誤處理
  • 錯誤處理的原則就是不能丟棄任何有返回err的呼叫,不要使用 _ 丟棄,必須全部處理。接收到錯誤,要麼返回err,或者使用log記錄下來
  • 儘早return:一旦有錯誤發生,馬上返回
  • 儘量不要使用panic,除非你知道你在做什麼
  • 錯誤描述如果是英文必須為小寫,不需要標點結尾
  • 採用獨立的錯誤流進行處理
// 錯誤寫法
if err != nil {
    // error handling
} else {
    // normal code
}

// 正確寫法
if err != nil {
    // error handling
    return // or continue, etc.
}
// normal code

6、測試

單元測試檔名命名規範為 example_test.go
測試用例的函式名稱必須以 Test 開頭,例如:TestExample
每個重要的函式都要首先編寫測試用例,測試用例和正規程式碼一起提交方便進行迴歸測試