如何在Go语言中创建单向通道?


在使用Go语言通道时,可能会有明确的通信意图、增强的通信安全性、封装等等需要创建单向通道的情况。在这篇Go语言文章中,我们将学习如何使用只发送通道方法、只接收通道方法、接口以及类型转换方法来创建单向通道。

双向通道允许通道数据被传输和接收。有时您可能希望强制执行单向通信,限制发送或接收操作。

语法

ch := make(chan<- string)

声明一个名为“ch”的只发送通道。

go sendOnlyChannel(ch, &wg)

我们使用“go”关键字启动一个新的goroutine。这里的go关键字正在执行SendOnlyChannel()函数。

var wg sync.WaitGroup

Sync.WaitGroup被定义为一个变量,用于同步goroutine。

方法1:使用只发送通道

此方法涉及通过在通道声明期间省略接收箭头(<-)来指定通道方向来创建单向通道。

算法

  • 创建一个名为“sendOnlyChannel”的函数,该函数接受一个同步指针和一个只发送通道作为参数。

  • 在“sendOnlyChannel”方法中创建一个包含字符串“Hi”、“There”、“from”、“send-only”和“channel”的消息切片。

  • 发送完所有消息后,使用close()方法关闭只发送通道。

  • 使用“wg”WaitGroup变量同步goroutine。

  • 应使用for range循环迭代通过只发送通道“ch”接收到的消息。

  • 使用fmt.Println()方法打印收到的每条消息。

示例

在下面的示例中,我们将看到如何使用只发送通道将值发送到另一个goroutine,而接收goroutine将处理消息。

package main

import (
   "fmt"
   "sync"
)

func sendOnlyChannel(ch chan<- string, wg *sync.WaitGroup) {
   defer wg.Done()

   messages := []string{"Hi", "There", "from", "send-only", "channel!"}

   for _, msg := range messages {
      ch <- msg   }

   close(ch) 
}

func main() {
   ch := make(chan string)
   var wg sync.WaitGroup

   wg.Add(1)
   go sendOnlyChannel(ch, &wg)

   for msg := range ch {
      fmt.Println("Received:", msg)
   }

   wg.Wait() 
}

输出

Received: Hi 
Received: There 
Received: from 
Received: send-only 
Received: channel!

方法2:使用只接收通道

此方法涉及通过在通道声明期间省略发送箭头(<-)来指定通道方向来创建单向只接收通道。

算法

  • 在Go环境中设置“fmt”和“sync”包。

  • 创建一个“receiveOnlyChannel”函数,该函数有两个参数:一个只接收通道(-chan int)和一个同步引用。

  • 在“receiveOnlyChannel”函数内使用defer语句来发出函数完成信号,并使用wg.Done()方法发出goroutine完成信号。

  • 在for range循环之后使用close()函数结束通道。

  • 打印“接收完成”以显示通道已接收所有值。

  • 在主函数中使用make()方法构造只接收通道“ch”。发送完所有值后,使用close()函数关闭通道。

  • 最后,在关闭receiveOnlyChannel goroutine之前,使用Wait()函数等待其完成。

示例

在下面的示例中,我们将看到如何使用只接收通道将值发送到另一个goroutine。

package main

import (
   "fmt"
   "sync"
)

func receiveOnlyChannel(ch <-chan int, wg *sync.WaitGroup) {
   defer wg.Done()

   for num := range ch {
      fmt.Println("Received:", num)
   }

   fmt.Println("Receiving complete")
}

func main() {
   ch := make(chan int)
   var wg sync.WaitGroup

   wg.Add(1)
   go receiveOnlyChannel(ch, &wg)

   for i := 1; i <= 6; i++ {
      ch <- i
   }

   close(ch)
   wg.Wait() 
}

输出

Received: 1 
Received: 2 
Received: 3 
Received: 4 
Received: 5 
Received: 6
 
Receiving complete

方法3:使用类型转换

此方法涉及通过使用类型转换来创建单向通道。我们可以将双向通道转换为只发送通道或只接收通道。

算法

  • 添加所需的包(fmt)。

  • 使用make()函数创建一个名为ch的双向通道。

  • 使用类型转换(chan<- int)(ch)将双向通道ch转换为只发送通道sendOnlyCh。

  • 要向只发送通道发送值,请启动一个goroutine:在goroutine中使用for循环从1迭代到6。

  • 使用<-运算符将每个值传输到只发送通道sendOnlyCh。

  • 发送完所有值后,使用close()函数关闭只发送通道。

  • 在主goroutine中使用for range循环处理和接收来自双向通道ch的值:使用for num:= range ch迭代接收到的每个值。

  • 使用fmt.Println()打印每个接收到的值。打印“程序完成”以显示程序已结束。

示例

以下示例涉及使用双向通道创建单向只发送通道,并显示发送和接收操作。

package main

import (
   "fmt"
)

func main() {
   ch := make(chan int)

   sendOnlyCh := (chan<- int)(ch)

   go func() {
      for i := 1; i <= 6; i++ {
         sendOnlyCh <- i
      }
      close(sendOnlyCh)
   }()

   for num := range ch {
      fmt.Println("Received:", num)
   }

   fmt.Println("Program complete")
}

输出

Received: 1 
Received: 2 
Received: 3 
Received: 4 
Received: 5 
Received: 6 

Program complete

结论

在本文中,我们讨论了各种Go语言通道创建技术。单向通道提供了一种在goroutine之间进行通信的强大方法,同时强制执行特定的数据传输或接收模式。上述方法可用于设计涉及数据传递的API,以将消息传播到多个通道。这些通道有助于增强可读性并减少信息的误用。

更新于:2023年7月5日

251 次查看

启动您的职业生涯

通过完成课程获得认证

开始
广告