1. 程式人生 > >golang學習(一)---------golang的命名規範

golang學習(一)---------golang的命名規範

gofmt

大部分的格式問題可以通過gofmt解決,gofmt自動格式化程式碼,保證所有的go程式碼一致的格式。

正常情況下,採用Sublime編寫go程式碼時,外掛GoSublilme已經呼叫gofmt對程式碼實現了格式化。

註釋

在編碼階段同步寫好變數、函式、包註釋,註釋可以通過godoc匯出生成文件。

註釋必須是完整的句子,以需要註釋的內容作為開頭,句點作為結尾。

程式中每一個被匯出的(大寫的)名字,都應該有一個文件註釋。

  • 包註釋

每個程式包都應該有一個包註釋,一個位於package子句之前的塊註釋或行註釋。

包如果有多個go檔案,只需要出現在一個go檔案中即可。

//Package regexp implements a simple library 
//for regular expressions.
package regexp 
  • 可匯出型別

第一條語句應該為一條概括語句,並且使用被宣告的名字作為開頭。

// Compile parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
func Compile(str string) (regexp *Regexp, err error) {

命名

使用短命名,長名字並不會自動使得事物更易讀,文件註釋會比格外長的名字更有用。

  • 包名

包名應該為小寫單詞,不要使用下劃線或者混合大小寫。

  • 介面名

單個函式的介面名以"er"作為字尾,如Reader,Writer

介面的實現則去掉“er”

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

兩個函式的介面名綜合兩個函式名

type WriteFlusher interface {
    Write([]byte) (int, error)
    Flush() error
}

三個以上函式的介面名,類似於結構體名

type Car interface {
    Start([]byte) 
    Stop() error
    Recover()
}
  • 混合大小寫

採用駝峰式命名

MixedCaps 大寫開頭,可匯出
mixedCaps 小寫開頭,不可匯出
  • 變數

    全域性變數:駝峰式,結合是否可匯出確定首字母大小寫
    引數傳遞:駝峰式,小寫字母開頭
    區域性變數:下劃線形式
    

控制結構

  • if

if接受初始化語句,約定如下方式建立區域性變數

if err := file.Chmod(0664); err != nil {
    return err
}
  • for

採用短宣告建立區域性變數

sum := 0
for i := 0; i < 10; i++ {
    sum += i
}
  • range

如果只需要第一項(key),就丟棄第二個:

for key := range m {
    if key.expired() {
        delete(m, key)
    }
}

如果只需要第二項,則把第一項置為下劃線

sum := 0
for _, value := range array {
    sum += value
}
  • return

儘早return:一旦有錯誤發生,馬上返回

f, err := os.Open(name)
if err != nil {
    return err
}
d, err := f.Stat()
if err != nil {
    f.Close()
    return err
}
codeUsing(f, d)

函式(必須)

  • 函式採用命名的多值返回
  • 傳入變數和返回變數以小寫字母開頭

    func nextInt(b []byte, pos int) (value, nextPos int) {
    

    在godoc生成的文件中,帶有返回值的函式宣告更利於理解

錯誤處理

  • error作為函式的值返回,必須對error進行處理
  • 錯誤描述如果是英文必須為小寫,不需要標點結尾
  • 採用獨立的錯誤流進行處理

不要採用這種方式

    if err != nil {
        // error handling
    } else {
        // normal code
    }

而要採用下面的方式

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

如果返回值需要初始化,則採用下面的方式

x, err := f()
if err != nil {
    // error handling
    return
}
// use x

panic

  • 儘量不要使用panic,除非你知道你在做什麼

import

  • 對import的包進行分組管理,而且標準庫作為第一組

    package main
    
    import (
        "fmt"
        "hash/adler32"
        "os"
    
        "appengine/user"
        "appengine/foo"
    
        "code.google.com/p/x/y"
        "github.com/foo/bar"
    )
    

縮寫

  • 採用全部大寫或者全部小寫來表示縮寫單詞

比如對於url這個單詞,不要使用

UrlPony

而要使用

urlPony 或者 URLPony  

引數傳遞

  • 對於少量資料,不要傳遞指標
  • 對於大量資料的struct可以考慮使用指標
  • 傳入引數是map,slice,chan不要傳遞指標

因為map,slice,chan是引用型別,不需要傳遞指標的指標

接受者

  • 名稱

統一採用單字母'p'而不是this,me或者self

    type T struct{} 

    func (p *T)Get(){}
  • 型別

對於go初學者,接受者的型別如果不清楚,統一採用指標型

func (p *T)Get(){}

而不是

func (p T)Get(){}   

在某些情況下,出於效能的考慮,或者型別本來就是引用型別,有一些特例

  • 如果接收者是map,slice或者chan,不要用指標傳遞
//Map
package main

import (
    "fmt"
)

type mp map[string]string

func (m mp) Set(k, v string) {
    m[k] = v
}

func main() {
    m := make(mp)
    m.Set("k", "v")
    fmt.Println(m)
}
//Channel
package main

import (
    "fmt"
)

type ch chan interface{}

func (c ch) Push(i interface{}) {
    c <- i
}

func (c ch) Pop() interface{} {
    return <-c
}

func main() {
    c := make(ch, 1)
    c.Push("i")
    fmt.Println(c.Pop())
}