Go语言中Channel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main

//通道
//通过通道共享内存(先入先出)

//channel 是一种类型 是引用类型 空值nil
//语法
//var 变量 chan 元素类型
//var ch1 chan int
//var ch2 chan bool

//需要通过make初始化
//make(chan 元素类型, [缓冲大小])

//var ch3 = make(chan []int)
//var ch4 = make(chan []string)

//操作
//发送 send 接收 receive 关闭 close
//发送和接收都使用 <-

//对一个关闭的通道发送值会导致panic
//接收 一个关闭的通道 会一直获取值 知道通道为空
//接收 一个关闭且没有值的通道 会得到对应类型的零值
//关闭一个已经关闭的通道会导致panic

//无缓冲的通道 = 阻塞通道 只能在有人接收值的时候才能发送值(必须有接收才能发送) = 同步通道
//有缓冲通道 make(chan int, x) x变量通道能存放元素的数量
//可以通过len 获取通道内元素的数量 cap获取通道的容量

//从通道中循环取值 for range

//单向通道 限制通道只能接收或发送

//chan<- int 只能发送的通道(可以发送不能接收)
func counter(out chan<- int) {
for i := 0; i < 100; i++ {
out <- i
}
close(out)
}

//<- chan int 只能接收的通道(可以接收不能发送)
func squarer(out chan <- int, in <- chan int) {
for i := range in {
out <- i
}
close(out)
}

//func rec(c chan int) {
// ret := <- c
// fmt.Println("接收成功", ret)
//}

func main() {
//定义一个有缓冲的通道
////ch5 := make(chan int, 1)
//ch5 := make(chan int)
//go rec(ch5)
////把10发送到ch5通道中
//ch5 <- 10
//fmt.Println("发送成功")

//从ch5通道接收值赋给变量a
//a := <- ch5
//从ch5通道接收值丢弃
//<- ch5

//关闭通道
//close(ch5)
//fmt.Println(a)

//ch := make(chan int, 5)
//对一个关闭的通道发送值会导致panic
//close(ch)
//ch <- 10
//接收 一个关闭的通道 会一直获取值 知道通道为空
//ch <- 10
//close(ch)
//x := <- ch
//fmt.Println(x)
//接收 一个关闭且没有值的通道 会得到对应类型的零值
//close(ch)
//x := <- ch
//fmt.Println(x)
//关闭一个已经关闭的通道会导致panic
//close(ch)
//close(ch)

//循环取值
//ch1 := make(chan int)
//ch2 := make(chan int)
//
//go func() {
// for i := 0; i < 10; i++ {
// ch1 <- i
// }
// close(ch1)
//}()
//
//go func() {
// for {
// ok判断通道是否关闭 ok为false 说明通道已关闭
// i, ok := <-ch1
// if !ok {
// break
// }
// ch2 <- i * i
// }
// close(ch2)
//}()
//
//for i := range ch2 {
// fmt.Println(i)
//}

////单向通道
//ch1 := make(chan int)
//ch2 := make(chan int)
//
//go counter(ch1)
//go squarer(ch2, ch1)
////循环获取通道中值
//for i := range ch2 {
// fmt.Println(i)
//}
}