Golang 学习摘录(一)

原创 2015年11月17日 18:08:15

Golang 学习摘录(一)

  1. 学过C,python,或者Java之类语言再来学习golang应该是无压力,看看语法就能写。语法上比较特殊的如下:

    • 声明变量并赋值使用 :=

      a, b := 1, 2 //声明变量a,b,并且赋值1,2

      a = 2 //a赋值2

    • if 不需要圆括号,并且可以执行表达式.for语句类似

      if x:=1; x<2 {

      }

    • String()函数<同java的toString(),对象的字符串形式>中如果有对自身的"%s"操作,将导致无穷递归调用。因为"%s"会调用String(),将对象转化为字符串形式。

      type MyString string

      func (m MyString) String() string {

          return fmt.Sprintf("MyString=%s", m) // Error: will recur forever.
          return fmt.Sprintf("MyString=%s", string(m)) // OK: note conversion.
      

      }

      string(m)将m转化为一个String对象,然后“%s”是作用在该String对象上,不是m本身,所以不回导致无穷递归

  2. defer有点finally的味道,但是又有不同

    for i := 0; i < 5; i++ {
        defer fmt.Printf("%d ", i)
    }
    

    Deferred functions are executed in LIFO后进先出<栈> order, so this code will cause 4 3 2 1 0

    func trace(s string) string {
        fmt.Println("entering:", s)
        return s
    }
    func un(s string) {
        fmt.Println("leaving:", s)
    }
    func a() {
        defer un(trace("a"))
        fmt.Println("in a")
    }
    func b() {
        defer un(trace("b"))
        fmt.Println("in b")
        a()
    }
    func main() {
        b()
    }

    The arguments to the deferred function (which include the receiver if the function is a method) areevaluated when the defer executes, not when the call executes.

    defer语句执行时,立即计算被defer的函数所需要的所有参数,而不是等到被defer的函数执行才计算该函数的参数。结果如下

    entering: b
    in b
    entering: a
    in a
    leaving: a
    leaving: b
    
  3. new and make

    new(T) returns a pointer to a newly allocated zero value of type T。new适合初始化0值对象,new(File) and &File{} are equivalent。new([]int) returns a pointer to a newly allocated, zeroed slice structure, that is, a pointer to a nil slice value.

    make(T, args) creates slices, maps, and channels only, and it returns an initialized (not zeroed) value of type T (not *T)

  4. Arrays

    Arrays are values. Assigning one array to another copies all the elements. 数组不是引用,是值,数组a赋值给b,直接拷贝成另一份b,结果是数组a,b独立,内容相同

    In particular, if you pass an array to a function, it will receive a copy of the array, not a pointer to it. 数组作为参数,传递的也是整个数组的值的拷贝,而不是指针

    以上两点与C语言不同,每次拷贝数组代价昂贵,如果希望类似C语言,可以传递指针。

  5. Slices

    Slices行为才与C的数组一致,是指针传递。Slices更常用。Slices底层是数组,只要不超过底层数组的容量,Slices地址不变。一旦添加元素导致超过底层数组的容量,就会reallocated重新分配。默认底层数组容量为cap(slice)。

  6. 特殊语法...(三个点的省略号)

    x := []int{1,2,3}

    y := []int{4,5,6}

    x = append(x, y...)//去掉...报错,因为y不是int类型

    fmt.Println(x)//有点类似Python对于字典**dict

  7. init函数

    每个源代码文件都可以有一个init函数,在该源代码文件的import语句执行完后,并且变量调用其initializers后执行init函数。一般用于检查该文件中的各种状态是否正确

  8. import for side effect

    有时候import一个library,并不是为了使用某个函数或者类,仅仅只是希望该library的init函数执行一次,做一下准备工作:

    import _ "net/http/pprof"//during its init function, the net/http/pprof package registers HTTP handlers that provide debugging information
    
  9. Channel

    管道常用于goroutine之间的通信,同步;Go不推荐使用共享内存,互斥元等方式通信。管道用于goroutine同步例子:

    c := make(chan int)  // 初始化一个不带缓存的管道
    go func() {
        list.Sort()
        c <- 1  // Send a signal; value does not matter.
    }()
    //新起一个goroutine,去做排序,排序完后向管道写入数据
    doSomethingForAWhile()
    <-c   // 阻塞等待管道有数据写入,即等待上面goroutine排序完成
    

    管道用作semaphore(信号量),比如限流,例子:

    var sem = make(chan int, 100)
    func Serve(queue chan *Request) {
    for req := range queue {
        tmp := req // Create new instance of req for every goroutine.
        sem <- 1  //信号量满时写入阻塞
        go func() {
            process(tmp)
            <-sem  //处理完一个请求释放一次信号量
        }()
    }
    }

    由于管道sem分配了buffer,size为100.所以前100个请求,可以不阻塞立即得到执行。后面的请求必须排队等待前面100个请求当中,有请求处理完毕(管道中有数据被读出),才能写入管道,得到处理。所以,这个例子,管道起到限流作用:并行处理的请求数不得超过100

  10. panic recover

    Go的异常处理机制,同try...except...

    Because recover always returns nil unless called directly from a deferred function, deferred code can call library routines that themselves use panic and recover without failing.

    func safelyDo(work *Work) {
    defer func() {
        if err := recover(); err != nil {
            log.Println("work failed:", err)
        }
    }()
    do(work)
    }

    do函数里出了panic异常,执行deferred函数func,func函数里,调用recover捕获异常。

版权声明:本文为博主原创文章,未经博主允许不得转载。博主地址 http://blog.csdn.net/secretx

相关文章推荐

Golang学习摘录(二)

Golang学习二 Full slice expressions切片操作 Python a[low: high: direction] 比如 a = [1, 2, 3], a[1:2:-1]负...
  • secretx
  • secretx
  • 2015年11月30日 16:36
  • 958

Golang学习摘录(三)

golang学习笔记(三) 方法(Method sets) The method set of any other type T consists of all methods decla...
  • secretx
  • secretx
  • 2016年02月24日 11:26
  • 509

golang学习手册

  • 2017年06月01日 13:40
  • 66KB
  • 下载

学习 Go 语言(Golang)最佳中文教程

  • 2015年07月10日 15:41
  • 1.07MB
  • 下载

【golang】Go语言学习-select用法

golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作。 示例: ch1 := make (chan ...

golang学习笔记

  • 2015年10月26日 16:11
  • 1.27MB
  • 下载

学习 Go 语言(Golang)

  • 2014年09月12日 09:48
  • 1.47MB
  • 下载

关于Golang中database/sql包的学习笔记

https://segmentfault.com/a/1190000003036452 因为最近在学习Go,所以找了revel这个框架来学习,感觉和php的面向对象有很大不同。revel...

学习golang的几本教材

  • 2014年01月17日 14:34
  • 4.12MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Golang 学习摘录(一)
举报原因:
原因补充:

(最多只允许输入30个字)