首页 > 编程笔记 > Go语言笔记 阅读:4

Go语言通道(channel)的创建和使用(非常详细,附带实例)

通道是 Go 语言在两个或多个协程(goroutine)之间的一种通信方式。通道可以让一个协程给另一个协程发送消息。当需要在协程之间共享一个数据资源时,通道是确保同步交换数据资源的方法。

协程与通道的关系如下图所示:


图 1 协程与channel(通道)的关系

多个协程为了争抢数据资源,势必会降低执行效率。为了保证执行效率不降低,协程之间通过通道进行通信,确保同一时刻只有一个协程访问通道,并执行发送和接收数据的操作。

通道就像队列一样,遵循“先入先出”的规则,保证发送和接收数据的顺序。

Go语言通道的声明和创建

在 Go 语言中,通道是一种特殊的数据类型。通道需要一个类型修饰。这样,通道的类型就是在其内部传输的数据的类型。

声明通道类型的语法格式如下:
var name chan type
参数说明如下:
为了创建通道,需要使用 make() 函数。创建通道的语法格式如下:
name := make(chan type)
参数说明如下:
在实际开发中,可以先声明通道,再创建通道。代码如下:
var chel chan string
chel = make(chan string)

还可以省去声明通道的步骤,直接使用 make() 函数创建通道。代码如下:
chel := make(chan string)

Go语言通道的基本操作

创建通道后,就可以使用通道执行发送和接收数据的操作了。

1) 使用通道发送数据

使用通道发送数据需要使用特殊的操作符“<-”,其语法格式如下:
name <- value
参数说明如下:
例如,创建一个可以传输任意类型的数据的通道,分别让其发送数字 711 和字符串“hello world”。关键代码如下:
//创建传输任意类型数据的通道
chel := make(chan interface{})
//使用通道发送数字711
chel <- 711
//使用通道发送字符串hello world
chel <- "hello"
把在通道内部传输的数据的类型设置为空接口类型,该通道就能够传输任意类型的数据。

2) 使用通道接收数据

使用通道接收和发送数据具有以下特性:
使用通道接收数据也要使用特殊的操作符“<-”,并有 4 种语法格式:
① 发送数据操作将被持续阻塞,直到通道传输的数据被接收。语法格式如下:
data := <-name
参数说明如下:
② 通道传输的数据被接收且不会发送阻塞。语法格式如下:
data, ok = <-name
参数说明如下:
③ 发送数据操作被持续阻塞,直到接收通道传输的数据,但是接收到的数据会被忽略。语法格式如下:
<-name

④ 使用 for range 语句接收通道传输的数据。语法格式如下:
for data := range name {
}
通道传输的数据是可以遍历的,遍历的结果就是接收到的数据。

下面的实例演示如何遍历通道传输的数据。

【实例】遍历通道传输的数据。创建传输int类型数据的通道。为匿名函数创建协程,其作用是使用通道发送数字 0~5。遍历并打印通道传输的数据。代码如下:
package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan int) // 创建传输int类型数据的通道
    go func() {
       for i := 0; i < 6; i+++ {
           ch <- i // 使用通道发送数字 0~5
           time.Sleep(1 * time.Second) // 延时 1s
       }
   }()
   // 遍历通道传输的数据
   for data := range ch {
       fmt.Println(data) // 如果遍历的结果是 5
       if data == 5 {
           break // 则不再接收通道传输的数据
       }
   }
}
运行结果如下:

0
1
2
3
4
5

3) 关闭通道

通道使用 Go 语言内置的 close() 函数设置标识,告诉 Go 程序当前通道已完成发送数据的操作。在使用 close() 函数关闭通道后,通道不再执行发送数据的操作。

close() 函数的语法格式如下:
close(name)
参数说明如下:

相关文章