golang中Channel通道(三)
一、select的用法
select 是Go中的一个控制结构。select语句类似于switch语句,但是select会随机执行一个可运行的case。如果没有case可运行,它将阻塞,直到有case可运行。
1、语法结构
select语句的语法结构和switch语句很相似,也有case语句和default语句:
select i{
case communication clause :
statement(s);
case communication clause :
statement(s);
/*你可以定义任意数量的case */
default : /*可选*/
statement(s);
}
2、说明:
每个case都必须是一个通信
所有channel表达式都会被求值
所有被发送的表达式都会被求值
如果有多个case都可以运行,select会随机公平地选出一个执行。其他不会执行。
否则:
如果有default子句,则执行该语句。
如果没有default字句,select将阻塞,直到某个通信可以运行;Go不会重新对channel或值进行求值。
实例:
package main
import (
"fmt"
"time"
)
func main() {
//select本身不带循环,需要外层的for
ch1:=make(chan int)
ch2:=make(chan int)
go func() {
time.Sleep(3*time.Second)
ch1 <- 100
}()
//select本身不带循环,需要外层的for
select {
case <-ch1:
fmt.Println("case1执行")
case <-ch2:
fmt.Println("case2执行")
case <-time.After(3*time.Second):
fmt.Println("case3执行")
//default:
// fmt.Println("default执行")
}
}
二、time包里边的channel相关函数
1、func NewTimer(d Duration) *Timer
2、func After(d Duration) <-chan Time
返回一个通道:chan,存储的是d时间间隔之后的当前时间
相当于:return NewTimer(d).C
底层实现
func After(d Duration) <-chan Time {
return NewTimer(d).C
}
package main
import (
"fmt"
"time"
)
//time包里边的channel相关函数
func main() {
//1、func NewTimer(d Duration) *Timer
//创建一个计时器,d时间后触发
timer:=time.NewTimer(2*time.Second)
fmt.Printf("%T\n",timer) //*time.Timer
fmt.Println(time.Now()) //2022-03-19 22:48:46.1562713 +0800 CST m=+0.004909501
//此处等待channel中的数值,会阻塞2秒
ch2 :=timer.C
fmt.Println(<-ch2) //2022-03-19 22:48:48.1665741 +0800 CST m=+2.015212301
//2、func After(d Duration) <-chan Time
ch := time.After(2*time.Second)
fmt.Printf("%T\n",ch) //<-chan time.Time
fmt.Println(time.Now())//2022-03-19 22:53:58.7445513 +0800 CST m=+2.007082401
fmt.Println(<-ch)//2022-03-19 22:54:00.7480015 +0800 CST m=+4.010532601
}