Go Channel

Channel在Go中充当goroutine之间通信的媒介。

我们知道goroutine用于创建并发程序。并发程序可以同时运行多个进程。

然而,有时可能会出现两个或多个goroutine需要相互通信的情况。在这种情况下,我们使用通道,它允许goroutine相互通信和共享资源。

在学习通道之前,请确保您已了解Go中的Goroutine如何工作


在Go中创建Channel

在Go中,我们使用make()函数来创建通道。例如,

channelName := make(chan int)

这里,

  • channelName - 通道的名称
  • (chan int) - 表示通道是整数类型

示例:Go Channel

package main
import "fmt"

func main() {
  
// create channel of integer type number := make(chan int)
// access type and value of channel fmt.Printf("Channel Type: %T\n", number) fmt.Printf("Channel Value: %v", number) }

输出

Channel Type: chan int
Channel Value: 0xc00007a060

在上面的示例中,我们使用make()函数创建了一个名为number的通道。这里,我们使用了格式说明符

  • %T - 打印通道的类型
  • %v - 打印通道的值

由于通道是整数类型(由chan int指定),我们得到相同的输出。

此外,通道的值是内存地址,它充当goroutine发送和接收数据以进行通信的媒介。


Golang Channel 操作

创建通道后,我们可以通过通道在不同的goroutine之间发送和接收数据。

1. 将数据发送到通道

将数据发送到通道的语法是

channelName <- data

这里<-运算符后的数据被发送到channelName

让我们看一些例子,

// send integer data to channel
number <- 15

// send string data
message <- "Learning Go Channel"

2. 从通道接收数据

从通道接收数据的语法是

<- channelName

这会访问channelName中的数据。

让我们看一些例子,

// receive data 15
<- number

// receive data "Learning Go Channel"
<- message

示例:Go Channel 操作

package main
import "fmt"

func main() {

  // create channel
  number := make(chan int)
  message := make(chan string)

  // function call with goroutine
  go channelData(number, message)

// retrieve channel data fmt.Println("Channel Data:", <-number) fmt.Println("Channel Data:", <-message)
} func channelData(number chan int, message chan string) {
// send data into channel number <- 15 message <- "Learning Go channel"
}

输出

Channel Data: 15
Channel Data:  Learning Go Channel

在上面的示例中,我们创建了两个名为numbermessage的通道。

这里,我们使用了<-运算符来执行发送和接收通道数据的操作。


通道的阻塞性

在Go中,通道会根据goroutine的状态自动阻塞发送和接收操作。

1. 当goroutine将数据发送到通道时,该操作将被阻塞,直到数据被另一个goroutine接收。例如,

package main
import "fmt"

func main() {

  // create channel
  ch := make(chan string)
 
// function call with goroutine go sendData(ch)
// receive channel data fmt.Println(<-ch)
} func sendData(ch chan string) {
// data sent to the channel ch <- "Received. Send Operation Successful"
fmt.Println("Message sent! Send Operation Complete") }

输出

Message sent! Send Operation Complete
Received. Send Operation Successful

在上面的示例中,我们创建了sendData() goroutine来向通道发送数据。该goroutine将字符串数据发送到通道。

sendData() goroutine将数据发送到通道时,该操作将被阻塞,直到另一个goroutine准备好接收数据。

main()函数内部,我们在从通道接收数据之前调用了sendData()

但是,sendData()函数的打印语句只有在数据成功发送并被主goroutine接收后才会执行。

并且,当通道准备好接收数据时,会打印goroutine发送的数据。

2. 当goroutine从通道接收数据时,该操作将被阻塞,直到另一个goroutine将数据发送到通道。例如,

package main
import "fmt"

func main() {

  // create channel
  ch := make(chan string)

// function call with goroutine go receiveData(ch)
fmt.Println("No data. Receive Operation Blocked")
// send data to the channel ch <- "Data Received. Receive Operation Successful"
} func receiveData(ch chan string) {
// receive data from the channel fmt.Println(<-ch)
}

输出

No data. Receive Operation Blocked
Data Received. Receive Operation Successful

在上面的示例中,我们创建了receiveData() goroutine来从通道接收数据。该goroutine从通道接收字符串数据。

如果通道尚未发送数据,它将打印“No data. Receive Operation Blocked”

main()函数内部,我们在将数据发送到通道之前调用了receiveData()。这就是为什么会打印第一个“No data...”

并且,当通道发送数据时,会打印goroutine接收到的数据。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战