真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Go編碼規(guī)范有哪些

本文小編為大家詳細(xì)介紹“Go編碼規(guī)范有哪些”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Go編碼規(guī)范有哪些”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

創(chuàng)新互聯(lián)是專業(yè)的延津網(wǎng)站建設(shè)公司,延津接單;提供成都網(wǎng)站制作、網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行延津網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!

1. 代碼風(fēng)格

1.1 代碼格式
  • 代碼必須用 gofmt 進(jìn)行格式化,goland 可以配置,可以自行搜索一下配置

  • 我們編寫(xiě)的代碼每行應(yīng)該不超過(guò) 120 個(gè)字符,超出部分用換行解決。

  • 單個(gè)文件最大行數(shù)最大不超過(guò) 800 行.

  • 單個(gè)函數(shù)最大行數(shù)不超過(guò) 80 行。

  • import 規(guī)范

    • 不要使用相對(duì)路徑引入包,例如 import ../util/net

    • 在導(dǎo)入包時(shí),多個(gè)相同包名沖突時(shí),必須使用導(dǎo)入別名

// bad
"github.com/google/uuid"

// good
uuid "github.com/google/uuid"
  • 導(dǎo)入的包建議分組,引用匿名包建議用一個(gè)新的分組,并加上注釋方便后面小伙伴閱讀

import (
    // Go 標(biāo)準(zhǔn)庫(kù)
    "fmt"

    //第三方包
    "github.com/jinzhu/gorm"
    "github.com/google/uuid"
    "github.com/go-redis/redis/v8"

    // 匿名包
    /import MySQL driver
    _"github.com/jinzhu/gorm/dialects/mysql"

    // 內(nèi)部包
    slice "xxx.local/pkg/v1/goslice"
    meta "xxx.local/pkg/v1/meta"
    gomap "xxx.local/pkg/v2/gomap")
1.2 聲明、初始化和定義
  • 一個(gè)函數(shù)需要使用多個(gè)變量時(shí),可以在函數(shù)最開(kāi)頭處使用 var 聲明。在函數(shù)外部聲明的變量不能使用 :=

var (
    port = 8081
    metricServerPort = 2001)
  • 在初始化結(jié)構(gòu)體用 &struct 代替 new(struct),確保與結(jié)構(gòu)體初始化一致,初始化結(jié)構(gòu)體時(shí)換行。

// bad
stu := new(S)
stu.Name = "張三"

// good
stu := &S{
    Name:"李四"
}
  • 使用 make 在聲明 map、array 等應(yīng)該指定容器的容量,從而達(dá)到預(yù)先分配內(nèi)容。

users := make(map[int]string, 10)tags := make([]int, 0, 10)
  • 使用標(biāo)準(zhǔn) var 關(guān)鍵字事,不要指定類(lèi)型,除非它與表達(dá)式的類(lèi)型不同。

// bad
var _f string F()

func F() string {
    return "hello world!"
}

// good 
var _f F()

func F() string {
    return "hello world!"
}
1.3 error 處理
  • 若函數(shù)返回 error, 必須對(duì) error 進(jìn)行處理,如果業(yè)務(wù)允許可以用 _ 接受忽略。對(duì)應(yīng) defer 可以不用顯式進(jìn)行處理。

// bad
func InitConfig() error {
    ...
}
InitConfig()


// good
func InitConfig() error {
    ...
}
err := InitConfig()
if err != nil {
    ...
}
// or 
_ := InitConfig()
  • error 作為返回值時(shí)必須作為最后一個(gè)參數(shù)返回

// bad
func InitConfig() (error,int) {
    ...
}

// good 
func InitConfig() (int, error) {
    ...
}
  • 錯(cuò)誤需要單獨(dú)處理,盡量不要與其他的邏輯耦合在一起。

// bad
res, err := InitConfig()
if err != nil || res != nil {
    return err
}

// good
res, err := InitConfig()
if err != nil {
    return err
}
if res != nil {
    return fmt.Errorf("invalid result")
}
1.4 panic處理
  • 業(yè)務(wù)代碼中禁止拋出 panic 錯(cuò)誤。

  • panic 只允許出現(xiàn)在在服務(wù)啟動(dòng)之前,如讀取配置、鏈接存儲(chǔ)(redis、mysql 等)。

  • 業(yè)務(wù)代碼中建議用 error 而不是 panic 來(lái)傳遞。

1.5 單元測(cè)試
  • 每個(gè)重要的函數(shù)都要編寫(xiě)測(cè)試用例,合并代碼要自動(dòng)化運(yùn)行一下所有的 test。

  • 文件命名 xxx_test.go。

  • 函數(shù)命名建議使用 Test函數(shù)名。

2. 命名規(guī)范

在每個(gè)語(yǔ)言中,命名規(guī)范在代碼規(guī)范中非常重要,一個(gè)統(tǒng)一的、精確的命名不僅僅可以提高代碼的可讀性,也可以讓人覺(jué)的這個(gè)同志真的會(huì)呀。牛!

2.1 包命名規(guī)范
  • 包名必須與目錄名一致(這和其他 php、Java 還是有一點(diǎn)不太一樣的),盡量采取有意義、簡(jiǎn)短的包名,不要與 go 的標(biāo)準(zhǔn)庫(kù)名稱一樣。

  • 包名小寫(xiě),沒(méi)有下劃線,可以使用中劃線隔開(kāi),使用多級(jí)目錄來(lái)劃分目錄。

  • 包名不要出現(xiàn)復(fù)數(shù)命名。

  • 包名命名盡量簡(jiǎn)單一目了然,ge:user、log。

2.2 文件命名規(guī)范
  • 文件名要見(jiàn)名思義,盡量簡(jiǎn)而短

  • 文件名小寫(xiě),組合詞用下劃線分割

2.3 函數(shù)命名規(guī)范
  • 與 php、Java 一樣,必須遵循駝峰規(guī)范,Go 語(yǔ)言中需要根據(jù)訪問(wèn)的控制決定大駝峰還是小駝峰。

  • 單元測(cè)試的函數(shù)用大駝峰,TestFunc。

2.4 結(jié)構(gòu)體命名規(guī)范
  • 與 php、Java 一樣,必須遵循駝峰規(guī)范,Go 語(yǔ)言中需要根據(jù)訪問(wèn)的控制決定大駝峰還是小駝峰。

  • 避免使用 info 、data 這種無(wú)意義的名稱。

  • 命名使用名詞而非動(dòng)詞。

  • 結(jié)構(gòu)體在聲明和初始化的時(shí)候需要換行,eg:

type Student struct{
    Name string
    Age uint8}student := Student{
    Name: "張三",
    Age: 18,}
2.5 變量命名規(guī)范
  • 和 php、Java 一樣,必須遵循駝峰規(guī)范,Go 語(yǔ)言中需要根據(jù)訪問(wèn)的控制決定大駝峰還是小駝峰。

  • 若變量為私有時(shí),可以使用小寫(xiě)命名。

  • 局部變量可以簡(jiǎn)寫(xiě),eg:i 表示 index。

  • 若變量代表 bool 值,則可以使用 Is 、Can、Has 前綴命名,eg:

var isExit boolvar canReturn bool
2.6 常量命名規(guī)范
  • 必須遵循駝峰規(guī)范,Go 語(yǔ)言中需要根據(jù)訪問(wèn)的控制決定大駝峰還是小駝峰。

  • 若代表枚舉值,需要先創(chuàng)建。

type Code intconst (
    ErrNotFound Code = iota
    ErrFatal)

3. 類(lèi)型

3.1 字符串

好像學(xué)過(guò)的語(yǔ)言中,都是從字符串開(kāi)始說(shuō)起的。就像寫(xiě)代碼第一行都是從 Hello World!一樣!同意的點(diǎn)贊哈。

  • 字符串判空值

// bad
if s == "" {
    ...}
 // good
 if len(s) == 0 {
    ...}
  • 字符串去除前后子串。

// bad
var s1 "hello world"var s2 "hello"var s3 strings.TrimPrefix(s1, s2)
// good
var s1 "hello world"var s2 "hello"var s3 stringif strings.HasPrefix(s1, s2){
    s3 = s1[len(s2):]}
3.2 切片 slice
  • 聲明 slice。

// bad
s := []string{}s := make([]string, 10)
// good
var s []string
s := make([]string, 0, 10)
  • 非空判斷。

//bad
if len(slice) >0 {
    ...}
 // good
 if slice != nil && len(slice) > 0 {
    ...}
  • slice copy。

// badvar b1,b2 []bytefor i, v := range b1 {
    b2[i] = v}for i := range b1 {
    b2[i] = b1[i]}// goodcopy(b2,b1)
  • slice 新增。

// bad
var a,b []intfor _, v := range a {
    b = append(b,v)}
// good
var a, b []int
b := append(b, a...)
3.4 結(jié)構(gòu)體 struct
  • 初始化需要多行。

type Student struct{
    Name string
    Age uint8}student := Student{
    Name: "張三",
    Age: 18,}

4. 控制語(yǔ)句

4.1 if
  • if 可以用局部變量的方式初始化。

if err := InitConfig; err != nil {
    return err}
4.2 for
  • 不允許在 for 中使用 defer, defer 只在函數(shù)結(jié)束時(shí)才會(huì)執(zhí)行。

// bad
for file := range files {
    fd, err := os.Open(file)
    if err != nil {
        return err    }
    defer fd.close()}
// good
    for file := range files{
    func() {
        fd,err := os.open(file)
        if err!=nil {
            return err        }
        defer fd.close()
    }()}
4.3 range
  • 如果不需要 key 直接用 _ 忽略,value 也一樣。

for _, v := range students {
    ...}for i, _ := range students {
    ...}for i, v := range students {
    ...}

注: 若操作指針時(shí)請(qǐng)注意不能直接用 s := v。想知道可以評(píng)論區(qū)告訴我哦!

4.4 switch
  • 和其他語(yǔ)言不一樣,必須要有 defalt

switch type {
    case 1:
        fmt.Println("type = 1")
        break
     case 2:
        fmt.Println("type = 2")
        break
     default :
        fmt.Println("unKnown type")}
4.5 goto
  • 業(yè)務(wù)中不允許使用 goto。

  • 框架和公共工具也不允許使用 goto。

5. 函數(shù)

  • 傳參和返回的變量小寫(xiě)字母。

  • 傳入?yún)?shù)時(shí)slice、map、interface、chan 禁止傳遞指針類(lèi)型。

  • 采用值傳遞,不用指針傳值。

  • 入?yún)€(gè)數(shù)不能超出 5 個(gè),超過(guò)的可以用 struct 傳值。

5.1 函數(shù)參數(shù)
  • 返回值超出 1 個(gè)時(shí),需要用變量名返回。

  • 多個(gè)返回值可以用 struct 傳。

5.2 defer
  • 當(dāng)操作資源、或者事物需要提交回滾時(shí),可以在創(chuàng)建開(kāi)始下方就使用 defer 釋放資源。

  • 創(chuàng)建資源后判斷 error,非 error 情況后在用 defer 釋放。

5.3 代碼嵌套
  • 為了代碼可讀性,為了世界和平,盡量別用太多的嵌套,因?yàn)檎娴暮茈y有人類(lèi)能看懂。

6. 日常使用感悟

  • 能不用全局變量就不用,可以用參數(shù)傳值的方式,這樣可以大大降低耦合,更有利于單元測(cè)試。

  • 衣服開(kāi)發(fā)中,在函數(shù)間多用 context 傳遞上下文,在請(qǐng)求開(kāi)始時(shí)可以生成一個(gè) request_id,便于鏈路、日志追蹤。

6.1 提高性能
  • 在業(yè)務(wù)開(kāi)發(fā)中,盡量使用 strconv 來(lái)替代 fmt。

  • 我們?cè)谑褂?string 字符串類(lèi)型時(shí),當(dāng)修改的場(chǎng)景較多,盡量在使用時(shí)用 []byte 來(lái)替代。因?yàn)槊看螌?duì) string 的修改都需要重新在申請(qǐng)內(nèi)存。

6.2 避免踩坑
  • append 要小心自動(dòng)擴(kuò)容的情況,最好在申明時(shí)分配好容量,避免擴(kuò)容所帶來(lái)的性能上的損耗以及分配新的內(nèi)存地址。若不能確定容量,應(yīng)選擇一個(gè)比較大一點(diǎn)的值。

  • 并發(fā)場(chǎng)景下,map 非線程安全,需要加鎖。還有一種評(píng)論區(qū)告訴我吧。

  • interface 在編譯期間無(wú)法被檢查,使用上會(huì)出現(xiàn) panic,需要注意

讀到這里,這篇“Go編碼規(guī)范有哪些”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。


網(wǎng)頁(yè)標(biāo)題:Go編碼規(guī)范有哪些
標(biāo)題來(lái)源:http://weahome.cn/article/gchodo.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部