休眠与计时器
本课属于 Coddy GO 学习旅程的“逻辑与流程”单元。第 64 课,共 68 课。
有时,你需要控制程序的运行时间。Go 在 time 包中提供了两个重要函数来实现这一点:time.Sleep 用于暂停运行,time.NewTicker 用于按固定间隔执行操作。
time.Sleep 函数会让程序暂停指定的时长。它接受一个 time.Duration 作为参数,并阻塞程序的执行,直到这段时间过去:
fmt.Println("Starting...")
time.Sleep(2 * time.Second)
fmt.Println("Two seconds have passed!")对于按固定间隔重复执行的操作,time.NewTicker 会创建一个计时器,每隔指定时间在通道上发送值。这适用于需要定期运行的任务:
ticker := time.NewTicker(1 * time.Second)
for i := 0; i < 3; i++ {
<-ticker.C // 等待下一次计时器触发
fmt.Println("Tick", i+1)
}这些计时函数对于在 Go 程序中创建延迟、实现超时和安排重复操作至关重要。
挑战
简单创建一个冥想计时器,使用 time.Sleep 在引导语之间暂停,并展示 Go 程序中的基本计时控制。
你会收到两个输入:
- 一个包含冥想步骤的字符串,格式为
"step1:duration,step2:duration,step3:duration"(例如:"Breathe in:3,Hold:2,Breathe out:4") - 一个包含重复循环次数的字符串(例如:
"5")
你的任务是:
- 通过按逗号拆分第一个输入,获取各个冥想步骤
- 对每个步骤,按冒号拆分,提取引导语和持续时间(秒)
- 使用
strconv包将持续时间字符串转换为整数 - 将第二个输入转换为整数,以获取循环次数
- 显示会话标题:
"=== MEDITATION TIMER ===" - 显示会话设置:
"Starting meditation session with [number_of_cycles] cycles" - 对每个循环(从循环 1 开始):
- 显示:
"--- Cycle [cycle_number] ---" - 对每个冥想步骤:
- 显示:
"[instruction]..." - 使用
time.Sleep暂停指定的时长(将时长乘以time.Millisecond,如time.Duration(duration) * time.Millisecond,这样检查就能快速完成;输出仍显示秒数) - 暂停后显示:
"[instruction] complete ([duration] seconds)"
- 显示:
- 完成一个循环中的所有步骤后,显示:
"Cycle [cycle_number] finished"
- 显示:
- 所有循环完成后,显示会话摘要:
"=== SESSION COMPLETE ===""Total cycles completed: [number_of_cycles]""Steps per cycle: [number_of_steps]""Total meditation time: [total_seconds] seconds"(将所有步骤的持续时间相加,再乘以循环次数)
- 显示完成消息:
"Meditation session finished - well done!"
使用 time 包执行休眠操作,使用 strings 包拆分输入字符串,使用 strconv 包将字符串转换为整数,并使用 fmt 包输出内容。请记住,time.Sleep 接受一个 time.Duration 参数,因此要先转换整数:time.Duration(duration) * time.Millisecond。实际计时器会使用 time.Second,但暂停整秒会导致检查超时。本挑战将展示如何使用 time.Sleep 在程序执行过程中创建定时暂停,可用于引导冥想或运动计时器等实际应用。
亲手试试
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
"time"
)
func main() {
// 使用 bufio.Scanner 读取输入,以正确处理空格
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
stepsInput := scanner.Text()
scanner.Scan()
cyclesInput := scanner.Text()
// 解析冥想步骤和循环次数
steps := strings.Split(stepsInput, ",")
cycles, _ := strconv.Atoi(cyclesInput)
// TODO: 在下方编写你的代码
// 解析每个步骤,提取指令和时长
// 访问 parts 切片前,记得检查元素是否足够
// 显示会话标题并完成设置
// 循环遍历各轮和各步骤
// 使用 time.Sleep 暂停:time.Duration(duration) * time.Millisecond
// 显示完成消息和总结
}这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: Go 在线编译器