You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中定时器结束时如何终止函数执行?

Go CLI测验程序问题解决方案

问题根源分析

  1. fmt.Scanln阻塞无法中断:默认的fmt.Scanln是阻塞调用,定时器触发后无法强制终止它,导致程序仍等待用户输入。
  2. 索引越界panic:主逻辑与定时器未同步,在超时触发或题目完成后,仍尝试访问超出题目切片长度的索引。

具体修复方案

1. 解决输入阻塞问题

将输入操作放到独立goroutine中,用channel传递输入结果,通过select同时监听定时器和输入channel,实现超时立即终止输入等待。

2. 解决索引越界问题

在循环中先判断是否还有未完成的题目,确保定时器触发后立即停止所有对题目切片的访问,从根源避免越界。

完整修正代码

package main

import (
	"fmt"
	"time"
)

func main() {
	// 示例题目列表,可替换为自定义内容
	questions := []string{
		"1+1=?",
		"2+3=?",
		"5-2=?",
	}
	answers := []string{"2", "5", "3"}

	correctCount := 0
	currentQuestionIdx := 0
	timer := time.NewTimer(10 * time.Second) // 设置10秒超时时间
	defer timer.Stop()

	fmt.Println("测验开始,你有10秒时间完成所有题目!")

	for currentQuestionIdx < len(questions) {
		fmt.Printf("第%d题:%s\n", currentQuestionIdx+1, questions[currentQuestionIdx])

		// 启动goroutine处理用户输入,避免阻塞主逻辑
		inputChan := make(chan string, 1)
		go func() {
			var userInput string
			fmt.Scanln(&userInput)
			inputChan <- userInput
		}()

		select {
		case userInput := <-inputChan:
			// 校验答案并更新计数
			if userInput == answers[currentQuestionIdx] {
				correctCount++
			}
			currentQuestionIdx++
		case <-timer.C:
			fmt.Println("\n时间到!测验结束")
			goto quizEnd // 直接跳转到结果统计环节
		}
	}

quizEnd:
	fmt.Printf("\n测验完成,你答对了%d/%d道题\n", correctCount, len(questions))
}

关键代码说明

  • 输入goroutine:把fmt.Scanln放到独立goroutine中,用带缓冲的inputChan传递结果,避免goroutine泄漏。
  • select分支:同时监听定时器信号和输入结果,超时触发时直接终止循环,不再等待用户输入。
  • 索引边界检查:循环条件currentQuestionIdx < len(questions)确保不会访问超出切片范围的索引,彻底避免越界panic。

内容的提问来源于stack exchange,提问作者avenmia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 13:47:10