久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      分享一套Go編碼規(guī)范!歡迎收藏!

      最近在項目中也 codereview 了不少 Go 語言的代碼,有必要總結(jié)下代碼規(guī)范,算是一個筆記記錄了。

      說在前面,這只是我們團隊的一套規(guī)范而已。

      今天我們聊一下 Go 的編碼規(guī)范,大概分為幾大模塊,如注包/變量/常量命名、基本語法、函數(shù)、錯誤處理、心得等?!就扑]:golang教程】

      1. 代碼風格

      1.1 代碼格式

      • 代碼必須用 gofmt 進行格式化,goland 可以配置,可以自行搜索一下配置
      • 我們編寫的代碼每行應該不超過 120 個字符,超出部分用換行解決。
      • 單個文件最大行數(shù)最大不超過 800 行.
      • 單個函數(shù)最大行數(shù)不超過 80 行。
      • import 規(guī)范
        • 不要使用相對路徑引入包,例如 import ../util/net
        • 在導入包時,多個相同包名沖突時,必須使用導入別名

      // bad "github.com/google/uuid"  // good uuid "github.com/google/uuid"
      登錄后復制

      • 導入的包建議分組,引用匿名包建議用一個新的分組,并加上注釋方便后面小伙伴閱讀

      import (     // Go 標準庫     "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 聲明、初始化和定義

      • 一個函數(shù)需要使用多個變量時,可以在函數(shù)最開頭處使用 var 聲明。在函數(shù)外部聲明的變量不能使用 :=,會踩坑,不知道的可以評論區(qū)留言(要評論不易呀)!

      var (     port = 8081     metricServerPort = 2001)
      登錄后復制

      • 在初始化結(jié)構(gòu)體用 &struct 代替 new(struct),確保與結(jié)構(gòu)體初始化一致,初始化結(jié)構(gòu)體時換行。

      // bad stu := new(S) stu.Name = "張三"  // good stu := &S{     Name:"李四" }
      登錄后復制

      • 使用 make 在聲明 map、array 等應該指定容器的容量,從而達到預先分配內(nèi)容。

      users := make(map[int]string, 10)tags := make([]int, 0, 10)
      登錄后復制

      • 使用標準 var 關(guān)鍵字事,不要指定類型,除非它與表達式的類型不同。

      // 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, 必須對 error 進行處理,如果業(yè)務允許可以用 _ 接受忽略。對應 defer 可以不用顯式進行處理。

      // bad func InitConfig() error {     ... } InitConfig()   // good func InitConfig() error {     ... } err := InitConfig() if err != nil {     ... } // or  _ := InitConfig()
      登錄后復制

      • error 作為返回值時必須作為最后一個參數(shù)返回

      // bad func InitConfig() (error,int) {     ... }  // good  func InitConfig() (int, error) {     ... }
      登錄后復制

      • 錯誤需要單獨處理,盡量不要與其他的邏輯耦合在一起。

      // 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è)務代碼中禁止拋出 panic 錯誤。
      • panic 只允許出現(xiàn)在在服務啟動之前,如讀取配置、鏈接存儲(redis、mysql 等)。
      • 業(yè)務代碼中建議用 error 而不是 panic 來傳遞。

      1.5 單元測試

      • 每個重要的函數(shù)都要編寫測試用例,合并代碼要自動化運行一下所有的 test。
      • 文件命名 xxx_test.go。
      • 函數(shù)命名建議使用 Test函數(shù)名。

      2. 命名規(guī)范

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

      2.1 包命名規(guī)范

      • 包名必須與目錄名一致(這和其他 php、Java 還是有一點不太一樣的),盡量采取有意義、簡短的包名,不要與 go 的標準庫名稱一樣。
      • 包名小寫,沒有下劃線,可以使用中劃線隔開,使用多級目錄來劃分目錄。
      • 包名不要出現(xiàn)復數(shù)命名。
      • 包名命名盡量簡單一目了然,ge:user、log。

      2.2 文件命名規(guī)范

      • 文件名要見名思義,盡量簡而短
      • 文件名小寫,組合詞用下劃線分割

      2.3 函數(shù)命名規(guī)范

      • 與 php、Java 一樣,必須遵循駝峰規(guī)范,Go 語言中需要根據(jù)訪問的控制決定大駝峰還是小駝峰。
      • 單元測試的函數(shù)用大駝峰,TestFunc。

      2.4 結(jié)構(gòu)體命名規(guī)范

      • 與 php、Java 一樣,必須遵循駝峰規(guī)范,Go 語言中需要根據(jù)訪問的控制決定大駝峰還是小駝峰。
      • 避免使用 info 、data 這種無意義的名稱。
      • 命名使用名詞而非動詞。
      • 結(jié)構(gòu)體在聲明和初始化的時候需要換行,eg:

      type Student struct{     Name string     Age uint8}student := Student{     Name: "張三",     Age: 18,}
      登錄后復制

      登錄后復制

      2.5 變量命名規(guī)范

      • 和 php、Java 一樣,必須遵循駝峰規(guī)范,Go 語言中需要根據(jù)訪問的控制決定大駝峰還是小駝峰。
      • 若變量為私有時,可以使用小寫命名。
      • 局部變量可以簡寫,eg:i 表示 index。
      • 若變量代表 bool 值,則可以使用 Is 、Can、Has 前綴命名,eg:

      var isExit boolvar canReturn bool
      登錄后復制

      2.6 常量命名規(guī)范

      • 必須遵循駝峰規(guī)范,Go 語言中需要根據(jù)訪問的控制決定大駝峰還是小駝峰。
      • 若代表枚舉值,需要先創(chuàng)建。

      type Code intconst (     ErrNotFound Code = iota     ErrFatal)
      登錄后復制

      3. 類型

      3.1 字符串

      好像學過的語言中,都是從字符串開始說起的。就像寫代碼第一行都是從 Hello World!一樣!同意的點贊哈。

      • 字符串判空值

      // 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. 控制語句

      4.1 if

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

      if err := InitConfig; err != nil {     return err}
      登錄后復制

      4.2 for

      • 不允許在 for 中使用 defer, defer 只在函數(shù)結(jié)束時才會執(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 {     ...}
      登錄后復制

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

      4.4 switch

      • 和其他語言不一樣,必須要有 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è)務中不允許使用 goto。
      • 框架和公共工具也不允許使用 goto。

      5. 函數(shù)

      • 傳參和返回的變量小寫字母。
      • 傳入?yún)?shù)時slice、map、interface、chan 禁止傳遞指針類型。
      • 采用值傳遞,不用指針傳值。
      • 入?yún)€數(shù)不能超出 5 個,超過的可以用 struct 傳值。

      5.1 函數(shù)參數(shù)

      • 返回值超出 1 個時,需要用變量名返回。
      • 多個返回值可以用 struct 傳。

      5.2 defer

      • 當操作資源、或者事物需要提交回滾時,可以在創(chuàng)建開始下方就使用 defer 釋放資源。
      • 創(chuàng)建資源后判斷 error,非 error 情況后在用 defer 釋放。

      5.3 代碼嵌套

      • 為了代碼可讀性,為了世界和平,盡量別用太多的嵌套,因為真的很難有人類能看懂。

      6. 日常使用感悟

      • 能不用全局變量就不用,可以用參數(shù)傳值的方式,這樣可以大大降低耦合,更有利于單元測試。
      • 衣服開發(fā)中,在函數(shù)間多用 context 傳遞上下文,在請求開始時可以生成一個 request_id,便于鏈路、日志追蹤。

      6.1 提高性能

      • 在業(yè)務開發(fā)中,盡量使用 strconv 來替代 fmt。
      • 我們在使用 string 字符串類型時,當修改的場景較多,盡量在使用時用 []byte 來替代。因為每次對 string 的修改都需要重新在申請內(nèi)存。

      6.2 避免踩坑

      • append 要小心自動擴容的情況,最好在申明時分配好容量,避免擴容所帶來的性能上的損耗以及分配新的內(nèi)存地址。若不能確定容量,應選擇一個比較大一點的值。
      • 并發(fā)場景下,map 非線程安全,需要加鎖。還有一種評論區(qū)告訴我吧。
      • interface 在編譯期間無法被檢查,使用上會出現(xiàn) panic,需要注意

      7. 總結(jié)

      本篇很講了 Go 語言的編碼規(guī)范,當時想說的,規(guī)范是大家預定的東西,每個公司、團隊都會有不一樣的規(guī)范,只要大家一起遵循就好啦。你可以根據(jù)自己團隊的需求,定一套屬于自己團隊的項目規(guī)范。如果想小伙伴一起遵循,可以借助一些工具來保障執(zhí)行度。

      講了很多,雖然很基礎(chǔ),希望對于剛剛轉(zhuǎn) Go 語言,或者剛學習 Go 語言的同學有幫助吧。今天就到這里了。希望得到大家的一鍵三連。感謝!

      本文系轉(zhuǎn)載,原文鏈接:mp.weixin.qq.com/s/lfjP9DEia2WL4Ua…

      php入門到就業(yè)線上直播課:立即學習
      全程直播 + 實戰(zhàn)授課 + 邊學 + 邊練 + 邊輔導

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號