1.传入channel的值是原来值的备份,从channel中取出来的值也是通道中值的备份。
2.如果想通过channel传送同一个值,那么可以传递这个值的指针
3.关闭channel要从发送端关闭,如果从接收端关闭会引发恐慌。
4.发送端关闭通道并不会影响接收端接收
5.带缓冲区和不带缓冲区的channel区别就是长度是否为0,不带缓冲区的channel长度就是0
6.操作未被初始化的通道会被永久阻塞
var demo chan int
//for会被永久阻塞
for i:=range demo{
}
7.从channel接收数据的方式
var demochan=make(chan int,10)
/*
if 方式
在通道未被关闭之前,若通道中没有值则会阻塞在if语句,若有则会取出。
若通道关闭,则ok是false,且if不再被阻塞
*/
for{
if value,ok:=<-demochan;ok{
fmt.println(value)
}else{
break
}
}
/*
for循环方式:
通道关闭之前,如果通道内有值则取出否则for阻塞
通道关闭之后,for就会退出来不再阻塞
*/
for for i:=range demochan{
fmt.Println(i)
}
/*
select方式
select 中每一个case的条件需要是一个对chan操作的条件
如果没有case可以被触发,则执行default,如果有多个case被触发,则会随机执行一个case
下面的例子每一次执行的结果都会不一样
*/
chanCap:=5
intchan:=make(chan int,chanCap)
for i:=0;i<chanCap;i++{
select{
case intchan<-1:
case intchan<-2:
case intchan<-3:
}
}
for i:=0;i<chanCap;i++{
fmt.Println(<-intchan)
}
/*
for与select共用
补充知识:
Loop可以标识Loop紧挨着下面代码的位置,代码中的Loop在for上面,最后的break Loop意思是break for循环而不是break select
*/
intChan:=make(chan int,10)
for i:=0;i<10;i++{
intChan<-i
}
close(intChan)
synChan:=make(chan struct{},1)
go func(){
Loop:
for{
select{
case e,ok:=<-intChan:
if !ok{
fmt.Println("End.")
break Loop
}
fmt.Printf("Received: %v\n",e)
}
}
synChan<- struct{}{}
}()
<-synChan