Go 語言學習筆記

1. go沒有static關鍵字

面向對象編程中,儘可能對函數進行封裝,對於沒有函數變量的對象,使用static關鍵字尤爲方便。
go中沒有static關鍵字,必須每次new一個出來。編程

type Handler struct {
}

func NewHandler() *Handler {
    h := &Handler{}
    return h
}

func (*Handler) Method_1 (){
    
}

func (*Handler) Method_2 () {
    
}

2. go沒有while; do...while循環

go語言裏面的for循環比較靈活json

func main(){
    for {
        fmt.Printf("while true\n")
        break
    }

    for i:=0; i < 5; i = i + 1 {
        fmt.Printf("while data:%d\n", i)
    }

    i := 0
    for i < 5 {
        fmt.Printf("while ok:%d\n", i)
        i = i + 1
    }
}

3. go每一個協程都必須捕獲panic

go中每一個協程都必須捕獲panic, 不然任何一個協程問題,都會致使整個程序dump掉。數組

func no_panic_get(a, b int){
    /* //每一個go協程都必須捕獲panic, 不然整個程序都會panic
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("no_panic_get, err:%v\n", r)
        }
    }()
    */
    c :=  a / b
    fmt.Printf("no_panic_get res:%v\n", c)
}

func main(){
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("exec failed, err:%v\n", r)
        } else {
            fmt.Printf("exec success\n")
        }
    }()

    go no_panic_get(1,0)    //no_panic_get沒有捕獲panic, 程序直接panic崩潰
    time.Sleep(time.Duration(5 * time.Second))
}

4. go中巧用defer函數逆序執行

defer函數,是在函數最後執行的。
屬於先申明,後執行原則;多個defer,申明時入棧,出棧時執行,也就是逆序執行。
只要第一個申明的defer,做爲最後一個捕獲panic程序執行就能夠。函數

func main(){
    defer func() {
        fmt.Printf("defer func1\n")
    } ()

    defer func() {
        fmt.Printf("defer func2\n")
    } ()

    fmt.Printf("main func\n")
}

5. go中巧用interface

interface相似C/C++中的void*類型,能夠將任何類型轉爲interface類型。
不一樣的是, interface能夠肯定保存的是那種類型的數據. 使用 v.(type)ui

type A struct {
    age int
    sex string
}

type B struct {
    peer []string
    name string
}

func main(){
    aData := &A{age:19}
    bData := &B{[]string{"zhangsan", "lisi"},"wang"}

    ctx := make(map[string]interface{}) //容器
    ctx["1"] = aData
    ctx["2"] = bData
    for _, v := range ctx {
        switch v.(type) {
        case *A:
            fmt.Printf("type A %v\n", v)
        case *B:
            fmt.Printf("type B %v\n", v)
        default:
            fmt.Printf("type unkown\n")
        }
    }
}

6. go注意大小寫

go中大小寫區分訪問權限, 在定義函數,定義變量時須要注意。
小寫變量,不能被json序列化。
小寫函數,外部不能訪問。
go1.4 以前版本中, map[int]string, 由於key是int不能正確序列號。指針

type Stu struct {
    Age int
    Name string
}
func main(){
    ctx := make(map[int]*Stu)
    ctx[1] = &Stu{12,"li"}  //按照定義順序初始化
    ctx[2] = &Stu{ Age:18}  //初始化部分字段; 其餘字段默認值
    jsonres, _ := json.Marshal(ctx)
    result := string(jsonres)
    fmt.Printf("%s\n", result)

    newctx := make(map[int]*Stu)
    if err := json.Unmarshal([]byte(result), &newctx); err == nil { //第二個參數須要是一個指針
        for k, v := range newctx{
            fmt.Printf("k:%v val:%v\n", k, v)
        }
    }
}

7. go中變量申明後都有默認值

在go語言中,任何類型在聲明後沒有賦值的狀況下,都對應一個零值。code

  • 整形如int八、byte、int1六、uint、uintprt等,默認值爲0
  • 浮點類型如float3二、float64,默認值爲0
  • 布爾類型bool的默認值爲false
  • 複數類型如complex6四、complex128,默認值爲0+0i
  • 字符串string的默認值爲""
  • 錯誤類型error的默認值爲nil
  • 對於一些複合類型,如指針、切片、字典、通道、接口,默認值爲nil。而數組的默認值要根據其數據類型來肯定。例如:var a [4]int,其默認值爲[0 0 0 0]

8. go中可使用fmt構造一個error類型返回

go語言函數是支持多返回值的,所以在寫go函數時,都會帶一個error類型返回值表示是否有錯誤。
可使用fmt構造一個error返回。協程

func getError() error {
    a := 1
    b := 0
    return fmt.Errorf("a/b is not vaild, a:%d b:%d", a, b)
}
func main(){
    fmt.Printf("err[%v]", getError())
}
相關文章
相關標籤/搜索