ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 定时器 ~~~ type Timer struct { C<-chan Time r runtimeTimer } ~~~ ## Timer 一个定时器,代表未来的一个单一事件,你可以告诉timer你要等待多长时间,它提供一个channel,在将来的那个时间channel提供了一个时间值 ## 延时 **time.NewTimer时间到了,只响应一次** ~~~ func main() { //time.NewTimer时间到了,只响应一次 //创建一个定时器,设置时间为2s,2s后,往time通道写内容(当前时间) timer := time.NewTimer(2 * time.Second) fmt.Println("当前时间: ", time.Now()) //2s后,往timer.c写数据,有数据后,就可以读取 t := <-timer.C //channel没有数据前后阻塞 fmt.Println("t = ", t) } ~~~ **time.After(2 * time.Second)延迟多少秒产生个事件** ~~~ func main() { //定时2秒,2秒后产生一个事件,往channel里面写内容 <-time.After(2 * time.Second) fmt.Println("时间到") } ~~~ ## 停止 关闭定时器,定时器就不起作用了 ~~~ func main() { timer := time.NewTimer(3 * time.Second) go func() { <-timer.C fmt.Println("子协程可以打印了,因为定时器的时间到了") }() //关闭定时器 timer.Stop() for { } } ~~~ ## 重置 ~~~ func main() { timer := time.NewTimer(3 * time.Second) //重置上面的那个无效 flag := timer.Reset(1 * time.Second) fmt.Println(flag) //true <-timer.C fmt.Println("时间到") } ~~~ # Ticker 定时触发的计时器,它**会以一个间隔(interval)往channel发送一个事件(当前时间),而channel的接收者可以以固定的时间间隔从channel中读取事件** ~~~ func main() { ticker := time.NewTicker(1 * time.Second) i := 0 for { <-ticker.C i++ fmt.Println("i = ", i) if i ==5 { //停止ticker ticker.Stop() break } } } ~~~ # 不断取出数据 ~~~ intChan2 := getIntChan() for elem := range intChan2 { fmt.Printf("The element in intChan2: %v\n", elem) } ~~~ 我把调用getIntChan得到的结果值赋给了变量intChan2,然后用for语句循环地取出了该通道中的所有元素值,并打印出来。 这里的for语句也可以被称为带有range子句的for语句。它的用法我在后面讲for语句的时候专门说明。现在你只需要知道关于它的三件事。 一、这样一条for语句会不断地尝试从intChan2种取出元素值,即使intChan2被关闭,它也会在取出所有剩余的元素值之后再结束执行。 二、当intChan2中没有元素值时,它会被阻塞在有for关键字的那一行,直到有新的元素值可取。 三、假设intChan2的值为nil,那么它会被永远阻塞在有for关键字的那一行。 这就是带range子句的for语句与通道的联用方式。不过,它是一种用途比较广泛的语句,还可以被用来从其他一些类型的值中获取元素。除此之外,Go 语言还有一种专门为了操作通道而存在的语句:select语句