go语言实践笔记

Posted by onceme on Monday, December 3, 2018

TOC

  • 使用recover()捕捉panic时,只能捕捉直接调用的方法,通过go命令调用的代码块中抛出的panic,则无法捕捉

    package main
    
    import (
    "fmt"
    "errors"
    )
    
    func main() {
    fmt.Println("Enter function main.")
    defer func(){
    fmt.Println("Enter defer function.")
    if p := recover(); p != nil {
    fmt.Printf("panic: %s\n", p)
    }
    fmt.Println("Exit defer function.")
    }()
    // 引发 panic。
    go func() {
    	panic(errors.New("something wrong"))
    }()
    fmt.Println("Exit function main.")
    }
    
  • 不能循环引用

  • 默认按值传递

  • Golang 交叉编译,编译可以在其他系统运行的目标文件

变量

  • 整数相除,默认得到向下取整的整数

    func main(){
    var a int = 10;
    var b int = 6;
    //整数相除,默认得到向下取整的整数
    c := float64(a/b)
    //c := float64(float64(a)/float64(b))
    
    
    fmt.Println(c)
    }
    
  • map数据结构类似于java中的HashMap,能够自动扩容,非并发安全,并且key是无序的

  • 外部有同名变量的情况下,重新定义,会自动生成局部变量

    var a int;
    if(1){
    a := 1; //这里的变量a是if代码块内部的局部变量
    }
    
  • string与byte slice 转换

    str := []byte("string ...")
    
  • 变量作用域

    • go中函数可以直接使用全局变量,不像php中需要用global $var来引入
    • 所以在函数中不经声明直接使用变量时,一定要确定自己是不是要用全局变量
    • 文件中的变量声明会在main函数之前执行,要考虑这个是否符合预期,尤其是声明的时候依赖main函数初始化的全局变量时
  • 使用协程时,要考虑如果要既要使用全局变量,又要做不同协程间的隔离,那么就要借用面向对象中this这个概念,就是每次先初始化一个对象,然后再把这个实例放入协程中,这样不同的协程就是不同的实例了

    obj := newObj()
    go obj.run()
    
  • 可以使用 json.Marshal() 来讲多层嵌套的数据结构转为json

    • 不过decode的时候只能一层层进行反向操作了
  • 使用bufio 来进行输出缓冲,避免频繁的磁盘io代理的性能损失

  • 不同的包要避免互相引用,会造成死循环,导致报错

  • 日志输出

    • 对每一条日志设置一个等级
    • 对当前输出,设置一个等级
    • 输出等级大于日志等级才输出
    • 这样就避免调试信息需要手动的进行开关
  • 需要暴露到包外的变量与方法,首字母必须大写

  • 判断字典是否存在某个key

    if _, ok := m[key]; ok {
        return m[key]
    }
    
  • go的变量声明比较怪异,类型放在变量名的后面

    var num int32  
    
    //对于被基本数据类型,需要显性的进行实例化才能使用
    
    //map
    var UserMap map[string]string
    
    //使用make分配内存
    UserMap = make(map[string]string)
    //类型加花括号来实例化
    UserMap = map[string]string{}
    
    //自定义类型
    var UserRow StructUser
    UserRow = new(StructUser)
    
    
    UserRow = StructUser{}
    
  • 用 new 分配内存 内建函数 new 本质上说跟其他语言中的同名函数功能一样:new(T) 分配了零值填充的 T 类型的内存空间,并且返回其地址,一个 *T 类型的值。用 Go 的术语说,它返回了一个指针,指向新分配的类型 T 的零值。记住这点非常重要。 这意味着使用者可以用 new 创建一个数据结构的实例并且可以直接工作。

  • 务必记得 make 仅适用于 map,slice 和 channel,并且返回的不是指针。应当用 new获得特定的指针。


comments powered by Disqus
Ï