channel的单向用法与select,range简单使用

上篇文章介绍了channel的数据结构,这篇文章就不在过多讲述了
先来了解一下单向channel是如何实现的

  • channel可以通过参数传递,单向channel只是对channel的一种使用限制,就这跟C语言使用const修饰函数参数为只读是一个道理的
  • func readChan(chanName <-chan int);通过形参限定函数内部只能从channel中读取数据
  • func writeChan(chanName chan<- int);通过形参限定函数内部只能向channel中写入数据
  • 下面用简单的代码演示一个简单的示例程序:
    func readChan(chanName <-chan int) {
      <- chanName
    }
    func writeChan(chanName chan<- int) {
      chanName <- 1 7.
    } 
    func main() {
      var mychan = make(chan int, 10) 
      writeChan(mychan)
      readChan(mychan) 
    }
  • 上面的代码可以看出mychan是个正常的channel,而readChan()参数限制了传入的channel只能用来读,writeChan()参数限制了传 入的channel只能用来写,这样就实现了单向管道的简单使用。

使用select可以监控多channel,比如监控多个channel,当其中某一个channel有数据时,就从其读出数据。

package main
import (
    "fmt"
    "time"
)
func addNumberToChan(chanName chan int) {
     for {
        chanName <- 1time.Sleep(1 * time.Second)
        }
}
func main() {
    var chan1 = make(chan int, 10)
    var chan2 = make(chan int, 10)
    go addNumberToChan(chan1)
    go addNumberToChan(chan2)
    for {
        select {
        case e := <- chan1:
            fmt.Printf("Get element from chan1: %d\n", e)
        case e := <- chan2:
            fmt.Printf("Get element from chan2: %d\n", e)
        default:
            fmt.Printf("No element in chan1 and chan2.\n")
            time.Sleep(1 * time.Second)
        }
    }
}
  • 以上程序中创建两个channel:chan1和chan2。函数addNumberToChan()函数会向两个channel中周期性写入数 据。通过select可以监控两个channel,任意一个可读时就从其中读出数据,想知道程序如何输入可以把代码复制到编辑器中运行一下就知道了哈,这里就不贴运行后的结果了,不过可以知道的是上面的程序从channel中读出数据的顺序是随机的,事实上select语句的多个case执行顺序是随机的

  • 关于select的运行原理是这样的,select的case语句读channel不会阻塞,尽管channel中没有数据。这是由于case语句编译后调用读channel时会明确传入不阻塞的参数,此时读不到数据时不会将当前goroutine加入到等待队列,而是直接返回,select数据结构方面我还在研究,后面出一遍文章进行讲解。

通过range可以持续从channel中读出数据,就跟在遍历一个数组一样,当channel中没有数据时会阻塞当前goroutine,与读channel时阻塞处理机制一样。

 func chanRange(chanName chan int) {
            for e := range chanName {
                fmt.Printf("Get element from chan: %d\n", e)
            }
}

以上程序在运行时需要注意:如果向此channel写数据的goroutine退出时,系统检测到这种情况后会panic,否则range将会永久阻塞。

这些是我本人整理的资料结合自身的理解写出来的关于channel的单向用法和select,range的简单用法,还有很多不足希望大家指点并留言告知,技术在于积累,摸索,分享,才能进步,希望这篇文章可以帮到有需要的伙伴吧

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!