长安链 DApp 开发必学 Go 18:操作管道

109 阅读1分钟

俺已经知道管道是啥了,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,先这样,下一章做个烧脑的练习。