channel使用法则

Channel操作方式和状态

channel只有三种操作方式

  1. Read
  2. Write
  3. Close

有4种状态

  1. nil
  2. 打开且非空
  3. 打开且空
  4. 关闭的

有三种类型

  1. 只写
  2. 只读
  3. 可读可写

不同的操作对不同状态的channel产生的影响

操作方式Channel状态结果
Readnil阻塞
Read打开且非空输出值
Read打开且空阻塞
Read关闭的false
Read只写编译错误
Writenil阻塞
Write打开的但填满的阻塞
Write打开且但为填满的写入值
Write关闭的panic
Write只读编译错误
Closenilpanic
Close打开且非空关闭channel,读取成功直到通道耗尽,然后读取默认值
Close打开且空关闭channel,督导生产者的默认任职
Close关闭的panic
Close只读编译错误

怎样避免panic

编译错误我们通过编译器就可以防止了,但是我们怎么能避免panic呢。我们已经知道了panic的出现时机,避免出现这种情况就可以了
panic的三种情况

  1. 写入关闭的channel
  2. 关闭关闭的channel
  3. 关闭为nil的channel

首先我们将channel分为两组,

  1. channel的生成者
    1. 实例化channel
    2. 执行写操作
    3. 关闭channel
    4. 执行以上3点,并通过只读channel将他们暴露出去
  2. channel的消费者
    1. 要知道channel是否关闭了
    2. 正确处理阻塞

示例

package main

import "fmt"

func main() {
	// channel 拥有者
	chOwner := func() <-chan interface{} {
		// 实例化channel
		ch := make(chan interface{})
		go func() {
			// 写入完成后,关闭channel
			defer close(ch)
			for i := 0; i < 10; i++ {
				// 拥有者负责写入
				ch <- i
			}
		}()
		// 将只读channel 返回
		return ch
	}
	chCon := func(ch <-chan interface{}) {
		// 只需要知道channel何时被关闭的即可
		for i := range ch {
			fmt.Println(i)
		}
	}

	ch := chOwner()
	chCon(ch)
}

版权声明:本文为dalaowei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。