The Timer type represents a single event. When the Timer expires, the current time will be sent on C, unless the Timer was created by AfterFunc. A Timer must be created with NewTimer or AfterFunc.
type Timer struct {
    C <-chan Time
    // contains filtered or unexported fields
}
下面select是一直阻塞的
func GoAfter1() {
	timer := time.NewTimer(time.Second)
	select {
	case <-timer.C:
		fmt.Println("时间到了,玩游戏")
	}
	// 函数下面能运行到吗?
	fmt.Println("上面阻塞了,所以最后才能到这")
}
看下面的select运行几次
func GoAfter2() {
	timer := time.NewTimer(time.Second)
	go func() {
		// 看select运行几次
		select {
		case <-timer.C:
			fmt.Println("时间到了,玩游戏")
		}
	}()
	// 函数下面能当然能运行
	fmt.Println("所以最后才能到这")
	time.Sleep(time.Second * 3)
}
#代码输出
所以最后才能到这
时间到了,玩游戏
PASS
ok      go-newbase/time/timer-base      3.200s
加上for循环呢?
func GoAfter3() {
	timer := time.NewTimer(time.Second)
	go func() {
		// 看select运行几次
		for {
			select {
			case <-timer.C:
				fmt.Println("时间到了,玩游戏")
			}
		}
	}()
	// 函数下面能当然能运行
	fmt.Println("所以最后才能到这")
	time.Sleep(time.Second * 3)
}
#代码输出
所以最后才能到这
时间到了,玩游戏
PASS
ok      go-newbase/time/timer-base      3.207s
下面是实现一直运行,就需要重置定时器
func GoAfter4() {
	timer := time.NewTimer(time.Second)
	go func() {
		// 看select运行几次
		for {
			select {
			case <-timer.C:
				fmt.Println("时间到了,玩游戏")
				timer.Reset(time.Second)
			}
		}
	}()
	// 函数下面能当然能运行
	fmt.Println("所以最后才能到这")
	time.Sleep(time.Second * 3)
}
#代码输出
所以最后才能到这
时间到了,玩游戏
时间到了,玩游戏
时间到了,玩游戏
PASS
ok      go-newbase/time/timer-base      3.211s
因为下面函数不是阻塞的,主线程退出,所以没执行
func AfterPrint() {
	time.AfterFunc(time.Second, func() {
		fmt.Println("时间已到,吃饭")
	})
}
# 代码输出
啥也没输出
更改能输出的
func AfterPrint() {
	time.AfterFunc(time.Second, func() {
		fmt.Println("时间已到,吃饭")
	})
	
	time.Sleep(time.Second * 2)
}
# 代码输出
时间已到,吃饭
PASS
ok      go-newbase/time/timer-base      2.207s
一个自动收报机持有一个通道,它每隔一段时间就发送一个时钟的“滴答声”。
A Ticker holds a channel that delivers `ticks‘ of a clock at intervals.
type Ticker struct {
    C <-chan Time // The channel on which the ticks are delivered.
    // contains filtered or unexported fields
}
package main
import (
	"fmt"
	"time"
)
func main() {
	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()
	done := make(chan bool)
	go func() {
		time.Sleep(3 * time.Second)
		done <- true
	}()
	for {
		select {
		case <-done:
			fmt.Println("Done!")
			return
		case t := <-ticker.C:
			fmt.Println("Current time: ", t)
		}
	}
}
# 代码输出
Current time:  2020-11-20 09:31:02.598433 +0800 CST m=+1.003463301
Current time:  2020-11-20 09:31:03.5981403 +0800 CST m=+2.003170601
Current time:  2020-11-20 09:31:04.5986842 +0800 CST m=+3.003714501
Done!
func (t *Ticker) Reset(d Duration)
Reset stops a ticker and resets its period to the specified duration. The next tick will arrive after the new period elapses.
func (t *Ticker) Stop()
Stop turns off a ticker. After Stop, no more ticks will be sent. Stop does not close the channel, to prevent a concurrent goroutine reading from the channel from seeing an erroneous "tick".
原文:https://www.cnblogs.com/maomaomaoge/p/14128787.html