通道创建
c:=make(chan int) // 无缓冲
c:=make(chan int,5) //有缓冲
通道赋值取值
num:= <- c // 将c中值赋给num
c <- num // 将num赋值给c
channel 超过缓冲区会阻塞,直到把值拿走
package main
import “fmt”
func main() {
c := make(chan int)
go func() {
for i := 0; i < 5; i++ {
c <- i
}
//close可以关闭一个channel
close(c)
}()
//可以使用range来迭代不断操作channel
for data := range c {
fmt.Println(data)
}
fmt.Println(“Main Finished..”)
}
select操作
1 .基本使用
跟 switch-case 相比,select-case 用法比较单一,它仅能用于 信道/通道 的相关操作。
select {
case 表达式1:
case 表达式2:
default:
}
package main
import (
“fmt”
)
func main() {
c1 := make(chan string, 1)
c2 := make(chan string, 1)
c2 <- "hello"
select {<br /> case msg1 := <-c1:<br /> fmt.Println("c1 received: ", msg1)<br /> case msg2 := <-c2:<br /> fmt.Println("c2 received: ", msg2)<br /> default:<br /> fmt.Println("No data received.")<br /> }<br />}<br />运行select段时,若没有匹配的会执行default,若都没有匹配则进入阻塞,直到某个case 命中,若一直没有命中,会抛出deadlock错误
2. switch case 会顺序执行,而select case 若满足多个会随机选择一个执行。
3. select超时时间
当 case 里的信道始终没有接收到数据时,而且也没有 default 语句时,select 整体就会阻塞,但是有时我们并不希望 select 一直阻塞下去,这时候就可以手动设置一个超时时间。
package main
import (
“fmt”
“time”
)
func makeTimeout(ch chan bool, t int) {
time.Sleep(time.Second * time.Duration(t))
ch <- true
}
func main() {
c1 := make(chan string, 1)
c2 := make(chan string, 1)
timeout := make(chan bool, 1)
go makeTimeout(timeout, 2)
select {<br /> case msg1 := <-c1:<br /> fmt.Println("c1 received: ", msg1)<br /> case msg2 := <-c2:<br /> fmt.Println("c2 received: ", msg2)<br /> case <-timeout:<br /> fmt.Println("Timeout, exit.")<br /> }<br />}<br />**4. select case语句可以支持读和写两种操作**<br />package main
import (
“fmt”
)
func main() {
c1 := make(chan int, 2)
c1 <- 2<br /> select {<br /> case c1 <- 4:<br /> fmt.Println("c1 received: ", <-c1)<br /> fmt.Println("c1 received: ", <-c1)<br /> default:<br /> fmt.Println("channel blocking")<br /> }<br />}<br />select 与 switch 原理很相似,但它的使用场景更特殊
select 只能用于 channel 的操作(写入/读出),而 switch 则更通用一些;
select 的 case 是随机的,而 switch 里的 case 是顺序执行;
select 要注意避免出现死锁,同时也可以自行实现超时机制;
select 里没有类似 switch 里的 fallthrough 的用法;
select 不能像 switch 一样接函数或其他表达式。
- select 若第一个case 为空会调至第二个case执行