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())
}
相关文章
相关标签/搜索