前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >可能不知道的关于golang 的10件事情

可能不知道的关于golang 的10件事情

作者头像
李海彬
发布2018-03-27 13:06:47
6040
发布2018-03-27 13:06:47
举报
文章被收录于专栏:Golang语言社区
匿名结构体 最常见的匿名用法,不用单独定义一个结构体类型 var config struct { APIKey string OAuthConfig oauth.Config } config.APIKey = "BADC0C0A" 匿名结构体定义时并初始化 data := struct { Title string Users []*User }{ title, users, } err := tmpl.Execute(w, data) 匿名结构体slice定义并初始化 var indexRuneTests = []struct { s string rune rune out int }{ {"a A x", 'A', 2}, {"some_text=some_value", '=', 9}, {"☺a", 'a', 3}, {"a☻☺b", '☺', 4}, } 嵌套互斥锁 var hits struct { sync.Mutex n int } hits.Lock() hits.n++ hits.Unlock() 嵌套结构体 type Item struct { Title string URL string } type Response struct { Data struct { Children []struct { Data Item } } } 命令行 go doc 在命令行中,可以通过go doc 查看包相关接口信息 wdy@wdy:~/learn/program-learn/golang$ go doc sync package sync // import "sync" Package sync provides basic synchronization primitives such as mutual exclusion locks. Other than the Once and WaitGroup types, most are intended for use by low-level library routines. Higher-level synchronization is better done via channels and communication. Values containing the types defined in this package should not be copied. func NewCond(l Locker) *Cond type Cond struct { ... } type Locker interface { ... } type Mutex struct { ... } type Once struct { ... } type Pool struct { ... } type RWMutex struct { ... } type WaitGroup struct { ... } wdy@wdy:~/learn/program-learn/golang$ go doc sync Mutex type Mutex struct { // Has unexported fields. } A Mutex is a mutual exclusion lock. Mutexes can be created as part of other structures; the zero value for a Mutex is an unlocked mutex. func (m *Mutex) Lock() func (m *Mutex) Unlock() wdy@wdy:~/learn/program-learn/golang$ go doc sync.mutex.lock func (m *Mutex) Lock() Lock locks m. If the lock is already in use, the calling goroutine blocks until the mutex is available. 在同一个channel上进行读写操作 battle是一个阻塞channel,当多个goroutine执行warrior的时候,最先执行到select的goroutine进入到 case battle <- name: 此时其他goroutine会阻塞在select上,name进入battle的瞬间,阻塞等待的goroutine的其中一个会进入到 case opponent := <-battle: battle数据被读取后,阻塞等待的剩余的goroutine的其中一个会进入到 case battle <- name: 按照如上流程反复直到所有goroutine执行完毕。 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 } } 可以看到每次结果都是不一样的 wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go Go beat Python C++ beat C Java beat Perl wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go Perl beat Java Python beat Go C beat C++ wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go C++ beat C Java beat Perl Python beat Go wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go Go beat Python Perl beat Java C beat C++ wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go Python beat Go C beat C++ Java beat Perl wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go Go beat Python Perl beat Java C beat C++ wdy@wdy:~/learn/program-learn/golang$ go run learnchannel.go Go beat Python C beat C++ Java beat Perl 利用close来向其他goroutine广播 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 } } 结果 2 waiting... 1 waiting... 3 waiting... 0 waiting... 0 done! 3 done! 2 done! 1 done! 利用nil通道的特性 goroutine对于值为nil的channel进行接受或发送操作时,会永久block type Work struct { Job string } func (w Work) Do() { fmt.Println("do", w.Job) } func (w Work) Refuse() { fmt.Println(w.Job + "stopped") } func makeWork(ch chan Work) { for { time.Sleep(500 * time.Millisecond) ch <- Work{Job: "job"} } } 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 } } } 结果 do job worker 0 processed {job} do job worker 1 processed {job} do job worker 2 processed {job} do job worker 3 processed {job} do job worker 0 processed {job} do job worker 1 processed {job} do job worker 2 processed {job} do job worker 3 processed {job} do job worker 0 processed {job} worker 0 quitting worker 1 quitting worker 2 quitting worker 3 quitting jobstopped worker 0 refused {job} jobstopped worker 1 refused {job} jobstopped worker 2 refused {job} jobstopped worker 3 refused {job}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-07-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档