Go的几个小技巧
1.匿名结构体
1.全局配置结构体 var config struct {// 定义一个用于全局配置结构体 APIKey string OAuthConfig oauth.Config } config.APIKey = "BADC0C0A" 2. data := struct {//匿名结构体的定义 Title string Users []*User }{//同时初始化 title, users, } err := tmpl.Execute(w, data) (比 map[string]interface{} 消耗更小和更安全)
2.select中使用空channel
func worker(i int, ch chan Work, quit chan struct{}) { for { select { case w := <-ch: if quit == nil { w.Refuse(); fmt.Println("worker", i, "refused", w) break } w.Do(); fmt.Println("worker", i, "processed", w) case <-quit: fmt.Println("worker", i, "quitting") quit = nil } } } func main() { ch, quit := make(chan Work), make(chan struct{}) go makeWork(ch) for i := 0; i < 4; i++ { go worker(i, ch, quit) } time.Sleep(5 * time.Second) close(quit) time.Sleep(2 * time.Second) }
3.使用close广播
func waiter(i int, block, done chan struct{}) { time.Sleep(time.Duration(rand.Intn(3000)) * time.Millisecond) fmt.Println(i, "waiting...") <-block fmt.Println(i, "done!") done <- struct{}{} } func main() { block, done := make(chan struct{}), make(chan struct{}) for i := 0; i < 4; i++ { go waiter(i, block, done) } time.Sleep(5 * time.Second) close(block) for i := 0; i < 4; i++ { <-done } }
4.使用channel接受发送消息。
package main import "fmt" var battle = make(chan string) func warrior(name string, done chan struct{}) { select { case opponent := <-battle: fmt.Printf("%s beat %s\n", name, opponent) case battle <- name: // I lost :-( } done <- struct{}{} } func main() { done := make(chan struct{}) langs := []string{"Go", "C", "C++", "Java", "Perl", "Python"} for _, l := range langs { go warrior(l, done) } for _ = range langs { <-done } }