Go语言学习:Channel是什么?
来源:互联网 发布:ava编程思想 编辑:程序博客网 时间:2024/04/29 22:54
Channel是什么
在Go语言中,Channel即指通道类型。有时也用它来直接指代可以传递某种类型的值的通道。
类型表示法
chan T
- 关键字chan代表了通道类型的关键字,T则代表了该通道类型的元素类型。
- 例如:type IntChan chan int 别名类型IntChan代表了元素类型为int的通道类型。我们可以直接声明一个chan int类型的变量:var IntChan chan int,在被初始化后,变量IntChan就可以被用来传递int类型的元素值了。
chan<- T
- 只能被用来发送值, <-表示发送操作符
- <-chan T
- 接收通道值, <-表示接收操作符
值表示法
属性和基本操作
- 基于通道的通讯是在多个Goroutine之间进行同步的重要手段。而针对通道的操作本身也是同步的。
- 在同一时刻,仅有一个Goroutine能向一个通道发送元素值
- 同时也仅有一个Goroutine能从它那里接收元素值。
- 通道相当于一个FIFO先进先出的消息队列。
- 通道中的元素值都具有原子性。它们是不可被分割的。通道中的每一个元素都只可能被某一个Goroutine接收。已被接收的元素值会立刻被从通道中删除。
初始化通道
make(chan int, 10)
~ 表达式初始化了一个通道类型的值。传递给make函数的第一个参数表明此值的具体类型是元素类型为int的通道类型,而第二个参数则指该值在同一时刻最多可以容纳10个元素值。
package mainimport ( "fmt")type Person struct { Name string Age uint8 Address Addr}type Addr struct{ city string district string}func main(){ persionChan := make(chan Person,1) p1 := Person{"Harry",32,Addr{"Shanxi","Xian"}} fmt.Printf("P1 (1): %v\n",p1) persionChan <- p1 p1.Address.district = "shijingshan" fmt.Printf("P2 (2): %v\n",p1) p1_copy := <-persionChan fmt.Printf("p1_copy: %v\n",p1_copy)}
#go test.go 运行结果P1 (1): {Harry 32 {Shanxi Xian}}P2 (2): {Harry 32 {Shanxi shijingshan}}p1_copy: {Harry 32 {Shanxi Xian}}
通道中的元素值丝毫没有受到外界的影响。这说明了,在发送过程中进行的元素值属于完全复制。这也保证了我们使用通道传递的值的不变性。
单向通道
单向channel只能用于发送或者接收数据
var ch1 chan int // ch1是一个正常的channel,不是单向的
var ch2 chan<- float64// ch2是单向channel,只用于写float64数据
var ch3 <-chan int // ch3是单向channel,只用于读取int数据
channel是一个原生类型,因此不仅 支持被传递,还支持类型转换。只有在介绍了单向channel的概念后,读者才会明白类型转换对于
channel的意义:就是在单向channel和双向channel之间进行转换。
示例如下:
ch4 := make(chan int)
ch5 := <-chan int(ch4) // ch5就是一个单向的读取channel
ch6 := chan<- int(ch4) // ch6 是一个单向的写入channel
基于ch4,我们通过类型转换初始化了两个单向channel:单向读的ch5和单向写的ch6。
从设计的角度考虑,所有的代码应该都遵循“最小权限原则”
简单单向channel案例:
func Parse(ch <-chan int) { for value := range ch { fmt.Println("Parsing value", value) }}
关闭通道
close(strChan)
我们应该先明确一点:无论怎么样都不应该在接收端关闭通道。因为在那里我们无法判断发送端是否还会向该通道发送元素值。
如何判断一个channel是否已经被关 闭?我们可以在读取的时候使用多重返回值的方式:
str, ok := strChan,只需要判断第二个bool返回值即可,false表示strChan已经被关闭。
package mainimport ( "fmt" "time")func main(){ ch := make(chan int, 5) sign := make(chan int, 2) go func() { for i :=0;i<5;i++ { ch <- i time.Sleep(1 * time.Second) } close(ch) fmt.Println("The channel is closed.") sign <- 0 }() go func() { for { e, ok := <-ch fmt.Printf("%d (%v)\n", e,ok) if !ok { break } time.Sleep(2 * time.Second) } fmt.Println("Done.") sign <- 1 }() <- sign <- sign}
运行结果:
0 (true)
1 (true)
2 (true)
The channel is closed.
3 (true)
4 (true)
0 (false)
Done.
运行时系统并没有在通道ch被关闭之后立即把false作为相应接收操作的第二个结果,而是等到接收端把已在通道中的所有元素值都接收到之后才这样做。这确保了在发送端关闭通道的安全性。
完整示例
package mainimport ( "fmt" //"time")type Person struct { Name string Age uint8 Address Addr}type Addr struct{ city string district string}type PersonHandler interface { Batch(origs <-chan Person) <-chan Person Handle(orig *Person)}//类型声明type PersonHandlerImpl struct{}func(handler PersonHandlerImpl) Batch(origs <-chan Person) <-chan Person{ //初始化通道dests dests := make(chan Person, 100) go func(){ //需要被更改的人员信息会通过origs单向通道传递进来,那么我们就应该不断的试图从该通道中接收它们。 for p := range origs { //变更人员信息 handler.Handle(&p) //把人员信息发送给通道dests dests <- p } fmt.Println("All the information has been handled.") //关闭通道dests close(dests) }() return dests}func(handler PersonHandlerImpl) Handle(orig *Person){ //处理人员信息 if orig.Address.district == "Haidian"{ orig.Address.district = "ShiJingshan" }}func getPersonHandler() PersonHandler{ return PersonHandlerImpl{}}var personTotal = 200var persons []Person = make([]Person, personTotal)var personCount intfunc init(){ //初始化人员信息 for i := 0;i<personTotal;i++{ name := fmt.Sprintf("%s%d","P",i) p := Person{name,24,Addr{"Beijing","Haidian"}} persons[i] = p }}func main(){ handler := getPersonHandler() //初始化通道origs origs := make(chan Person, 100) //启用G2以处理人员信息 dests := handler.Batch(origs) //启用G3以获取人员信息 fecthPerson(origs) //启用G4以存储人员信息 sign := savePerson(dests) <- sign}//接受一个参数 是只允许写入origs通道func fecthPerson(origs chan<- Person){ go func(){ for _,p := range persons{ origs <- p } fmt.Println("All the information has been fetched.") close(origs) }()}//接受一个参数 是只允许读取dest通道 除非直接强制转换 要么你只能从channel中读取数据func savePerson(dest <-chan Person) <-chan byte { sign := make(chan byte,1) go func(){ for{ p, ok := <-dest if !ok { fmt.Println("All the information has been saved.") sign <- 0 break } savePerson1(p) } }() return sign}func savePerson1(p Person) bool { fmt.Println(p) return true}
运行后结果:
All the information has been fetched.
{P0 24 {Beijing ShiJingshan}}
{P1 24 {Beijing ShiJingshan}}
{P2 24 {Beijing ShiJingshan}}
{P3 24 {Beijing ShiJingshan}}
{P4 24 {Beijing ShiJingshan}}
{P5 24 {Beijing ShiJingshan}}
{P6 24 {Beijing ShiJingshan}}
{P7 24 {Beijing ShiJingshan}}
{P8 24 {Beijing ShiJingshan}}
{P9 24 {Beijing ShiJingshan}}
{P10 24 {Beijing ShiJingshan}}
{P11 24 {Beijing ShiJingshan}}
{P12 24 {Beijing ShiJingshan}}
{P13 24 {Beijing ShiJingshan}}
{P14 24 {Beijing ShiJingshan}}
{P15 24 {Beijing ShiJingshan}}
{P16 24 {Beijing ShiJingshan}}
{P17 24 {Beijing ShiJingshan}}
{P18 24 {Beijing ShiJingshan}}
{P19 24 {Beijing ShiJingshan}}
{P20 24 {Beijing ShiJingshan}}
{P21 24 {Beijing ShiJingshan}}
{P22 24 {Beijing ShiJingshan}}
{P23 24 {Beijing ShiJingshan}}
{P24 24 {Beijing ShiJingshan}}
{P25 24 {Beijing ShiJingshan}}
{P26 24 {Beijing ShiJingshan}}
{P27 24 {Beijing ShiJingshan}}
{P28 24 {Beijing ShiJingshan}}
{P29 24 {Beijing ShiJingshan}}
{P30 24 {Beijing ShiJingshan}}
{P31 24 {Beijing ShiJingshan}}
{P32 24 {Beijing ShiJingshan}}
{P33 24 {Beijing ShiJingshan}}
{P34 24 {Beijing ShiJingshan}}
{P35 24 {Beijing ShiJingshan}}
{P36 24 {Beijing ShiJingshan}}
{P37 24 {Beijing ShiJingshan}}
{P38 24 {Beijing ShiJingshan}}
{P39 24 {Beijing ShiJingshan}}
{P40 24 {Beijing ShiJingshan}}
{P41 24 {Beijing ShiJingshan}}
{P42 24 {Beijing ShiJingshan}}
{P43 24 {Beijing ShiJingshan}}
{P44 24 {Beijing ShiJingshan}}
{P45 24 {Beijing ShiJingshan}}
{P46 24 {Beijing ShiJingshan}}
{P47 24 {Beijing ShiJingshan}}
{P48 24 {Beijing ShiJingshan}}
{P49 24 {Beijing ShiJingshan}}
{P50 24 {Beijing ShiJingshan}}
{P51 24 {Beijing ShiJingshan}}
{P52 24 {Beijing ShiJingshan}}
{P53 24 {Beijing ShiJingshan}}
{P54 24 {Beijing ShiJingshan}}
{P55 24 {Beijing ShiJingshan}}
{P56 24 {Beijing ShiJingshan}}
{P57 24 {Beijing ShiJingshan}}
{P58 24 {Beijing ShiJingshan}}
{P59 24 {Beijing ShiJingshan}}
{P60 24 {Beijing ShiJingshan}}
{P61 24 {Beijing ShiJingshan}}
{P62 24 {Beijing ShiJingshan}}
{P63 24 {Beijing ShiJingshan}}
{P64 24 {Beijing ShiJingshan}}
{P65 24 {Beijing ShiJingshan}}
{P66 24 {Beijing ShiJingshan}}
{P67 24 {Beijing ShiJingshan}}
{P68 24 {Beijing ShiJingshan}}
{P69 24 {Beijing ShiJingshan}}
{P70 24 {Beijing ShiJingshan}}
{P71 24 {Beijing ShiJingshan}}
{P72 24 {Beijing ShiJingshan}}
{P73 24 {Beijing ShiJingshan}}
{P74 24 {Beijing ShiJingshan}}
{P75 24 {Beijing ShiJingshan}}
{P76 24 {Beijing ShiJingshan}}
{P77 24 {Beijing ShiJingshan}}
{P78 24 {Beijing ShiJingshan}}
{P79 24 {Beijing ShiJingshan}}
{P80 24 {Beijing ShiJingshan}}
{P81 24 {Beijing ShiJingshan}}
{P82 24 {Beijing ShiJingshan}}
{P83 24 {Beijing ShiJingshan}}
{P84 24 {Beijing ShiJingshan}}
{P85 24 {Beijing ShiJingshan}}
{P86 24 {Beijing ShiJingshan}}
{P87 24 {Beijing ShiJingshan}}
{P88 24 {Beijing ShiJingshan}}
{P89 24 {Beijing ShiJingshan}}
{P90 24 {Beijing ShiJingshan}}
{P91 24 {Beijing ShiJingshan}}
{P92 24 {Beijing ShiJingshan}}
{P93 24 {Beijing ShiJingshan}}
{P94 24 {Beijing ShiJingshan}}
{P95 24 {Beijing ShiJingshan}}
{P96 24 {Beijing ShiJingshan}}
{P97 24 {Beijing ShiJingshan}}
{P98 24 {Beijing ShiJingshan}}
{P99 24 {Beijing ShiJingshan}}
All the information has been handled.
{P100 24 {Beijing ShiJingshan}}
{P101 24 {Beijing ShiJingshan}}
{P102 24 {Beijing ShiJingshan}}
{P103 24 {Beijing ShiJingshan}}
{P104 24 {Beijing ShiJingshan}}
{P105 24 {Beijing ShiJingshan}}
{P106 24 {Beijing ShiJingshan}}
{P107 24 {Beijing ShiJingshan}}
{P108 24 {Beijing ShiJingshan}}
{P109 24 {Beijing ShiJingshan}}
{P110 24 {Beijing ShiJingshan}}
{P111 24 {Beijing ShiJingshan}}
{P112 24 {Beijing ShiJingshan}}
{P113 24 {Beijing ShiJingshan}}
{P114 24 {Beijing ShiJingshan}}
{P115 24 {Beijing ShiJingshan}}
{P116 24 {Beijing ShiJingshan}}
{P117 24 {Beijing ShiJingshan}}
{P118 24 {Beijing ShiJingshan}}
{P119 24 {Beijing ShiJingshan}}
{P120 24 {Beijing ShiJingshan}}
{P121 24 {Beijing ShiJingshan}}
{P122 24 {Beijing ShiJingshan}}
{P123 24 {Beijing ShiJingshan}}
{P124 24 {Beijing ShiJingshan}}
{P125 24 {Beijing ShiJingshan}}
{P126 24 {Beijing ShiJingshan}}
{P127 24 {Beijing ShiJingshan}}
{P128 24 {Beijing ShiJingshan}}
{P129 24 {Beijing ShiJingshan}}
{P130 24 {Beijing ShiJingshan}}
{P131 24 {Beijing ShiJingshan}}
{P132 24 {Beijing ShiJingshan}}
{P133 24 {Beijing ShiJingshan}}
{P134 24 {Beijing ShiJingshan}}
{P135 24 {Beijing ShiJingshan}}
{P136 24 {Beijing ShiJingshan}}
{P137 24 {Beijing ShiJingshan}}
{P138 24 {Beijing ShiJingshan}}
{P139 24 {Beijing ShiJingshan}}
{P140 24 {Beijing ShiJingshan}}
{P141 24 {Beijing ShiJingshan}}
{P142 24 {Beijing ShiJingshan}}
{P143 24 {Beijing ShiJingshan}}
{P144 24 {Beijing ShiJingshan}}
{P145 24 {Beijing ShiJingshan}}
{P146 24 {Beijing ShiJingshan}}
{P147 24 {Beijing ShiJingshan}}
{P148 24 {Beijing ShiJingshan}}
{P149 24 {Beijing ShiJingshan}}
{P150 24 {Beijing ShiJingshan}}
{P151 24 {Beijing ShiJingshan}}
{P152 24 {Beijing ShiJingshan}}
{P153 24 {Beijing ShiJingshan}}
{P154 24 {Beijing ShiJingshan}}
{P155 24 {Beijing ShiJingshan}}
{P156 24 {Beijing ShiJingshan}}
{P157 24 {Beijing ShiJingshan}}
{P158 24 {Beijing ShiJingshan}}
{P159 24 {Beijing ShiJingshan}}
{P160 24 {Beijing ShiJingshan}}
{P161 24 {Beijing ShiJingshan}}
{P162 24 {Beijing ShiJingshan}}
{P163 24 {Beijing ShiJingshan}}
{P164 24 {Beijing ShiJingshan}}
{P165 24 {Beijing ShiJingshan}}
{P166 24 {Beijing ShiJingshan}}
{P167 24 {Beijing ShiJingshan}}
{P168 24 {Beijing ShiJingshan}}
{P169 24 {Beijing ShiJingshan}}
{P170 24 {Beijing ShiJingshan}}
{P171 24 {Beijing ShiJingshan}}
{P172 24 {Beijing ShiJingshan}}
{P173 24 {Beijing ShiJingshan}}
{P174 24 {Beijing ShiJingshan}}
{P175 24 {Beijing ShiJingshan}}
{P176 24 {Beijing ShiJingshan}}
{P177 24 {Beijing ShiJingshan}}
{P178 24 {Beijing ShiJingshan}}
{P179 24 {Beijing ShiJingshan}}
{P180 24 {Beijing ShiJingshan}}
{P181 24 {Beijing ShiJingshan}}
{P182 24 {Beijing ShiJingshan}}
{P183 24 {Beijing ShiJingshan}}
{P184 24 {Beijing ShiJingshan}}
{P185 24 {Beijing ShiJingshan}}
{P186 24 {Beijing ShiJingshan}}
{P187 24 {Beijing ShiJingshan}}
{P188 24 {Beijing ShiJingshan}}
{P189 24 {Beijing ShiJingshan}}
{P190 24 {Beijing ShiJingshan}}
{P191 24 {Beijing ShiJingshan}}
{P192 24 {Beijing ShiJingshan}}
{P193 24 {Beijing ShiJingshan}}
{P194 24 {Beijing ShiJingshan}}
{P195 24 {Beijing ShiJingshan}}
{P196 24 {Beijing ShiJingshan}}
{P197 24 {Beijing ShiJingshan}}
{P198 24 {Beijing ShiJingshan}}
{P199 24 {Beijing ShiJingshan}}
All the information has been saved.
- Go语言学习:Channel是什么?
- Go语言学习:Channel
- Go语言学习笔记 --- concurrency、channel、select
- go语言channel关注点
- Go语言Channel详解
- Go语言 channel详解
- Go语言中Channel机制
- 【go 通道】go语言通道channel
- Go语言_Go语言的channel
- Go 语言中 channel 使用总结
- Go语言里channel的死锁
- Go语言 美妙的channel(上)
- Go语言 美妙的channel(下)
- [go语言]channel的一个“奇怪”特性
- TODO:Go语言goroutine和channel使用
- Go语言goroutine+channel+select简介
- go语言通道channel使用总结
- Go语言 Channel <- 箭头操作符 详解
- 一个老兵的linux学习和面试经验分享 【转载】
- Python——条件、循环和其他语句
- 配置安装Apache主服务发生错误:"(OS 5)拒绝访问。 : AH00369: Failed to open the Windows service manager, perh······ "
- Python——面向对象编程(引言)
- 有一定通用性的单调队列模板
- Go语言学习:Channel是什么?
- MyEclipse2015配置Tomcat方法
- android 测试以及工具的设置
- Python——类属性/实例属性
- C3P0整体类结构简单分析
- Oracle pl/sql编程 7---复合变量之记录类型
- Python——类、实例和其他对象的内建函数
- DES加密和解密工具,可以对字符串进行加密和解密操作
- liba52