D 的个人博客

但行好事莫问前程

  menu
417 文章
3974524 浏览
6 当前访客
ღゝ◡╹)ノ❤️

Go 边看边练 -《Go 学习笔记》系列(十四)(已完结)

上一篇: [1438938175118]


ToC


7.2.1 单向

可以将 channel 隐式转换为单向队列,只收或只发。

1c := make(chan int, 3) 2var send chan<- int = c // send-only 3var recv <-chan int = c // receive-only 4send <- 1 5// <-send // Error: receive from send-only type chan<- int 6<-recv 7// recv <- 2 // Error: send to receive-only type <-chan int

不能将单向 channel 转换为普通 channel

1d := (chan int)(send) // Error: cannot convert type chan<- int to type chan int 2d := (chan int)(recv) // Error: cannot convert type <-chan int to type chan int

7.2.2 选择

如果需要同时处理多个 channel,可使用 select 语句。它随机选择一个可用 channel 做收发操作,或执行 default case

在循环中使用 select default case 需要小心,避免形成洪水。

7.2.3 模式

用简单工厂模式打包并发任务和 channel

1func NewTest() chan int { 2 c := make(chan int) 3 rand.Seed(time.Now().UnixNano()) 4 5 go func() { 6 time.Sleep(time.Second) 7 c <- rand.Int() 8 }() 9 10 return c 11} 12 13func main() { 14 t := NewTest() 15 println(<-t) // 等待 goroutine 结束返回。 16}

channel 实现信号量 (semaphore)。

closed channel 发出退出通知。

select 实现超时 (timeout)。

1func main() { 2 w := make(chan bool) 3 c := make(chan int, 2) 4 5 go func() { 6 select { 7 case v := <-c: fmt.Println(v) 8 case <-time.After(time.Second * 3): fmt.Println("timeout.") 9 } 10 11 w <- true 12 }() 13 14 // c <- 1 // 注释掉,引发 timeout。 15 <-w 16}

channel 是第一类对象,可传参 (内部实现为指针) 或者作为结构成员。

1type Request struct { 2 data []int 3 ret chan int 4} 5 6func NewRequest(data ...int) *Request { 7 return &Request{ data, make(chan int, 1) } 8} 9 10func Process(req *Request) { 11 x := 0 12 for _, i := range req.data { 13 x += i 14 } 15 16 req.ret <- x 17} 18 19func main() { 20 req := NewRequest(10, 20, 30) 21 Process(req) 22 fmt.Println(<-req.ret) 23}

全系列完



社区小贴士

  • 关注标签 [golang] 可以方便查看 Go 相关帖子
  • 关注标签 [Go 学习笔记] 可以方便查看本系列
  • 关注作者后如有新帖将会收到通知

该文章同步自 黑客派


Related Issues not found

Please contact @88250 to initialize the comment

上午好!工作顺利嘛,不要久坐,多起来走动走动哦!