俺已经知道管道是啥了,Go 还提供了几个内置函数来操作管道。
上代码:
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) { // 计算斐波那契数列的函数
x, y := 0, 1
for i := 0; i < n; i++ {
c <- x // 送入管道
x, y = y, x+y
}
close(c) // 使用 close 关闭管道
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c { // 使用 range 来遍历管道,当检测到管道关闭时停止
fmt.Println(i)
}
}
使用 close 和 range 可以实现对管道的遍历。
继续上代码:
package main
import "fmt"
func fibonacci(c, quit chan int) { // 还是一个斐波那契数列函数,参数是两个管道
x, y := 0, 1
for {
select { // 使用 select 关键字来监听管道,进行相应操作
case c <- x:
x, y = y, x+y
case <- quit:
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c) // 从管道 c 中获取数据并打印
}
quit <- 0 // 结束,向 quit 管道发送数据
}()
fibonacci(c, quit)
}
上述代码演示了在主协程中,使用 select 对管道进行了监听,从而进行不同逻辑的处理。
如果俺想要主协程在等待时也做点什么:
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default: // 使用 default 关键字,让主协程处理自己的逻辑
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
ok,先这样,下一章做个烧脑的练习。