寻找golang的用法

实时更新

Go协程和通道。

等待goroutine结束

这是一篇很好的文章。

如果只是等待一个goroutine,可以使用channel来处理:

package main

import "log"

func main() {
  ch := make(chan int)
  go func(ch chan int) {
    // do something

    log.Printf("end of goroutine")
    ch <- 1
  }(ch)
  log.Printf("waiting for goroutine")
  <- ch
  log.Printf("end of main")
}

听说如果要等待多个goroutine,可以使用sync.WaitGroup。

package main

import (
  "log"
  "sync"
)

func main() {
  var wg sync.WaitGroup
  for i := 0; i < 3; i++ {
    wg.Add(1) // goroutineの数だけAdd()
    go func(i int) {
      defer wg.Done() // goroutineを抜けたらDone()
      log.Printf("goroutine: %d", i)
    }(i)
  }
  log.Printf("waiting for goroutines")
  wg.Wait() // ここでblockして待つ
  log.Printf("end of main")
}

顺便提一下,虽然是细节问题,但是要注意的是,由于Done() 被调用后立即结束,所以如果需要调用多个defer的情况下,如果没有将 Done() 放在第一个位置,其他的defer有可能会在 Done() 被调用之前就结束了整个进程(defer是按照LIFO的顺序执行的:http://blog.golang.org/defer-panic-and-recover)。

建设

将debug和release构建分开

我们使用build tag(构建标签)。例如,我们在env package中创建env_debug.go和env_release.go这两个文件,并分别在它们中写入构建条件。只有与build tag相匹配的文件才会被构建。

// +build !release

package env

const DEBUG = true
// +build release

package env

const DEBUG = false

在这种情况下,”// +build …”需要写在第一行,并且需要在第一行上留出一行空行。然后,我们通过import这个package来区分行为。

package main

import (
  "github.com/user/app/env"
)

func main() {
  if env.DEBUG {
    // ...
  }
}

调试版本

$ go build github.com/user/app

So, the release build is…

所以,发布版本是…

$ go build -a -tags=release github.com/user/app

如果只更改了build tag,则可能无法正确地重新构建所有库,所以最好使用-a选项。

其他

获取调用方的func。

pc, _, _, _ := runtime.Caller(1)
caller_name := runtime.FuncForPC(pc).Name();

如果有DEBUG标志等的话,可以做到。

import (
  "log"
  "runtime"
  "github.com/user/app/env"
)

func Debug(format string, args ...interface{}) {
  if env.DEBUG {
    pc, _, _, _ := runtime.Caller(1)
    caller_name := runtime.FuncForPC(pc).Name();

    log.Printf(caller_name + ": " + format, args...)
  }
}

所以,我觉得调试日志会更容易输出。

省略package的前缀

package main

import (
  "log"
)

func main() {
  log.Printf("hello")
}

要省略类似”log.”这样的文字,可以这样表达:

import (
  . "log"
)

假设如此

Printf("hello")

我可以写下重要的知识。同样的,

import (
  foo "log"
)

如果是这样的话 (如果这样的话)

foo.Printf("hello")

可以通过互联网访问。

另请参阅和参考网站

    • http://d.hatena.ne.jp/taknb2nch/20140414/1397459204

 

    http://jxck.hatenablog.com/entry/20130414/1365960707
广告
将在 10 秒后关闭
bannerAds