
我是刚开始开发玩具测验 cli 程序。我正在尝试实现一个计时器,以便当计时器结束时,测验就结束了。
这是我的初步实现。
func StartTimer(quizFinished chan bool, timer *time.Timer) {
// Start timer
<-timer.C
fmt.Println("\nQuiz has ended")
quizFinished <- true
return
}
func askQuestions(timer *time.Timer, questions []string, answers []string) []string {
var input string
var userAnswers []string
quizFinished := make(chan bool)
fmt.Println("Starting Quiz...")
go StartTimer(quizFinished, timer)
for index, element := range questions {
select {
case <-quizFinished:
fmt.Println("Quiz has ended")
return userAnswers
default:
fmt.Printf("Question %d: %s? ", index+1, element)
fmt.Scanln(&input)
userAnswers = append(userAnswers, input)
}
}
return userAnswers
}编辑实现
package main
import (
"bufio"
"flag"
"fmt"
"log"
"os"
s "strings"
"time"
)
func readFileData(fileName string) (questions []string, answers []string) {
file, err := os.Open(fileName)
if err != nil {
log.Fatalf("failed reading data from file: %v", err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
questionAndAnswer := s.Split(scanner.Text(), ",")
question, answer := questionAndAnswer[0], questionAndAnswer[1]
questions = append(questions, question)
answers = append(answers, answer)
}
return questions, answers
}
func askQuestions(timer *time.Timer, questions []string) []string {
var input string
var userAnswers []string = make([]string, 0, len(questions))
quizFinished := make(chan bool, 1)
fmt.Println("Starting Quiz...")
go func() {
<-timer.C
fmt.Println("\nquiz over...")
quizFinished <- true
}()
for index, element := range questions {
fmt.Printf("Question %d: %s? ", index+1, element)
answerCh := make(chan string, 1)
go func() {
fmt.Scanln(&input)
answerCh <- input
}()
select {
case <-quizFinished:
return userAnswers
case answer := <-answerCh:
userAnswers = append(userAnswers, answer)
}
}
return userAnswers
}
func main() {
fileNamePtr := flag.String("filename", "problems.csv", "Specify a file name to read in")
quizTimePtr := flag.Int("time", 5, "Specify how long the quiz should take")
flag.Parse()
timer := time.NewTimer(time.Duration(*quizTimePtr) * time.Second)
questions, answers := readFileData(*fileNamePtr)
// var userAnswers = askQuestions(timer, questions, answers)
var userAnswers = askQuestions(timer, questions)
correctAnswers := 0
incorrectAnswers := 0
for i := 0; i < len(answers); i++ {
if userAnswers[i] == answers[i] {
correctAnswers++
} else {
incorrectAnswers++
}
}
grade := float32(correctAnswers) / float32(len((questions)))
fmt.Printf("Total Questions: %d \n", len(questions))
fmt.Printf("Total Correct Answers: %d \n", correctAnswers)
fmt.Printf("Total Incorrect Answers: %d \n", incorrectAnswers)
fmt.Printf("Grade: %.0f%% \n", grade*100)
}我不断收到以下输出和错误:
Starting Quiz... Question 1: 5+5? 10 Question 2: 1+1? Quiz has ended 2 Returning from quiz... panic: runtime error: index out of range [2] with length 2 goroutine 1 [running]:
我对通道和 goroutine 的理解还不够深入,还无法理解正在发生的事情。预期的行为是当计时器停止时,它会打印“测验已结束”,并将一个值发送到 quizFinished 通道,该值在 select 语句中读取。我遇到的另一个问题是 Scanln 将在测验结束后等待用户输入。如有任何帮助,我们将不胜感激!
当你在主goroutine中调用Scanln函数时,它会暂停并等待用户输入。即使你的计时器在另一个 Goroutine 中完成并尝试通知主 Goroutine,主 Goroutine 也不会响应,因为它被“Scanner”阻止了。
这就是为什么即使计时器结束,Scanln 仍在等待用户输入。
package main
import (
"fmt"
"time"
)
func askQuestions(timer *time.Timer, questions []string) []string {
var input string
var userAnswers []string
quizFinished := make(chan bool, 1)
fmt.Println("start quiz...")
go func() {
<-timer.C
fmt.Println("\nquiz over...")
quizFinished <- true
}()
for index, element := range questions {
fmt.Printf("question %d: %s? ", index+1, element)
answerCh := make(chan string, 1)
go func() {
fmt.Scanln(&input)
answerCh <- input
}()
select {
case <-quizFinished:
fmt.Println("exit quiz...")
return userAnswers
case answer := <-answerCh:
userAnswers = append(userAnswers, answer)
}
}
return userAnswers
}
func main() {
timer := time.NewTimer(10 * time.Second)
questions := []string{"5+5", "1+1", "8+3"}
responses := askQuestions(timer, questions)
fmt.Println("answer:", responses)
}以上就是当 go 中计时器完成时如何从函数返回?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号