多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# **从通道接收数据** 这小节,你将了解到如何从通道读取数据。你可以执行 `<-c` 从名为 `c` 的通道读取一个值。如此,箭头方向是从通道到外部。 我将使用名为 `readCh.go` 的程序帮你理解怎样从通道读取数据,并它分为三部分介绍。 `readCh.go` 的第一段代码如下: ```go package main import ( "fmt" "time" ) func writeToChannel(c chan int, x int) { fmt.Println("l", x) c <- x close(c) fmt.Println("2", x) } ``` `writeToChannel()` 函数的实现与之前一样。 `readCh.go` 的第二部分如下: ```go func main() { c := make(chan int) go writeToChannel(c, 10) time.Sleep(1 * time.Second) fmt.Println("Read:", <-c) time.Sleep(1 * time.Second) ``` 上面的代码,使用 `<-c` 语法从 `c` 通道读取数据。如果你想要保存数据到名为 `k` 的变量而不只是打印它的话,你可以使用 `k := <-c` 表达式。第二个 `time.Sleep(1 * time.Second)` 语句给你时间来读取通道数据。 `readCh.go` 的最后一段代码如下: ```go _, ok := <-c if ok { fmt.Println("Channel is open!") } else { fmt.Println("Channel is closed!") } } ``` 从上面的代码,你能看到一个判断一个通道是打开还是关闭的技巧。当通道关闭时表明当前代码运行的还不错。但是,如果通道被打开,这里的代码就会丢弃从通道读取的值,因为在 `_, ok := <-c` 语句中使用了 `_` 字符。如果你也想在通道打开时读取通道的值,就使用一个有意义的变量名代替 `_`。 执行 `readCh.go` 产生如下输出: ```shell $ go run readCh.go 1 10 Read: 10 2 10 Channel is closed! $ go run readCh.go 1 10 2 10 Read: 10 Channel is closed! ``` 尽管输出不确定,但 `writeToChannel()` 函数的两个 `fmt->Println(x)` 表达式都被执行了,因为当你从通道读取数据时,它就被解除阻塞了。 >Bryan: 我的实验结果是第一个结果出现的概率大些。