从通道接收数据

这小节,您将了解到如何从通道读取数据。您可以执行 <-c 从名为 c 的通道读取一个值。如此,箭头方向是从通道到外部。

我将使用名为 readCh.go 的程序帮您理解怎样从通道读取数据,并它分为三部分介绍。

readCh.go 的第一段代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func writeToChannel(c chan int, x int) {
  7. fmt.Println("l", x)
  8. c <- x
  9. close(c)
  10. fmt.Println("2", x)
  11. }

writeToChannel() 函数的实现与之前一样。

readCh.go 的第二部分如下:

  1. func main() {
  2. c := make(chan int)
  3. go writeToChannel(c, 10)
  4. time.Sleep(1 * time.Second)
  5. fmt.Println("Read:", <-c)
  6. time.Sleep(1 * time.Second)

上面的代码,使用 <-c 语法从 c 通道读取数据。如果您想要保存数据到名为 k 的变量而不只是打印它的话,您可以使用 k := <-c 表达式。第二个 time.Sleep(1 * time.Second) 语句给您时间来读取通道数据。

readCh.go 的最后一段代码如下:

  1. _, ok := <-c
  2. if ok {
  3. fmt.Println("Channel is open!")
  4. }else {
  5. fmt.Println("Channel is closed!")
  6. }
  7. }

从上面的代码,您能看到一个判断一个通道是打开还是关闭的技巧。当通道关闭时,当前代码运行的还不错。但是,如果通道被打开,这里的代码就会丢弃从通道读取的值,因为在 _, ok := <-c 语句中使用了 _ 字符。如果您也想在通道打开时读取通道的值,就使用一个有意义的变量名代替 _

执行 readCh.go 产生如下输出:

  1. $go run readCh.go
  2. 1 10
  3. Read: 10
  4. Channel is closed!
  5. $go run readCh.go
  6. 1 10
  7. 2 10
  8. Read: 10
  9. Channel is closed!

尽管输出不确定,但 writeToChannel() 函数的两个 fmt->Println(x) 表达式都被执行了,因为当您从通道读取数据时,它就被解除阻塞了。