[英]How to read from stdin with goroutines in Golang?
有問題清單。 我向用戶顯示一個接一個的問題,然后等待用戶的回答。 每個問題都應在幾秒鍾內得到回答(例如5秒鍾)。 如果正確及時地回答了問題,那么用戶會得到一些意見。 我的代碼如下所示:
for i := 0; i < len(questions); i++ {
fmt.Println(questions[i].Text)
ans := make(chan int)
go func() {
fmt.Print("Enter answer ")
var u int
fmt.Scanf("%d\n", &u)
ans <- u
}()
select {
case userAnswer := <-ans:
if userAnswer == questions[i].Answer {
points++
}
case <-time.After(5 * time.Second):
fmt.Println("\n Time is over!")
}
}
接下來的問題是:如果用戶不回答問題,那么他將按預期收到消息“時間結束”。 但是下一個答案將不被處理,用戶應再次輸入。 看起來像下一個輸出:
question with answer 1
Enter answer: 1
1 is right answer
question with answer 2
Enter answer: 2
2 is right answer
question with answer 3
Enter answer:
Time is over!
question with answer 4
Enter answer: 4
4
4 is right answer
question with answer 5
Enter answer: 5
5 is right answer
用戶沒有回答問題3,因此他需要兩次回答問題4。 我知道這個問題是因為goroutines和channel。 但是我不明白,為什么沒有價值,那是在超時后從stdin中讀取,發送到“ ans”頻道或從中獲取的。
為什么超時后不能正確接收來自通道的值? 我該如何重寫代碼,以便用戶在上一個問題超時后無需重復輸入兩次?
對不起,英語不好,謝謝您的幫助。
這里發生的是,當您超時時,在上一個goroutine中仍然有一個fmt.Scanf
。 您還將在每個循環中分配一個新通道。 最終結果意味着來自問題3的掃描得到您的第一個輸入4,然后嘗試將其推入一個永遠不會被讀取的通道。 第二次輸入4時,它將被新的goroutine讀取,然后被推到您希望在其上找到用戶輸入的通道。
相反,我建議您將用戶輸入卸載到一個提供單個通道的goroutine中。
func readInput(input chan<- int) {
for {
var u int
_, err := fmt.Scanf("%d\n", &u)
if err != nil {
panic(err)
}
input <- u
}
}
然后像這樣處理您的問題:
func main() {
var points int
userInput := make(chan int)
go readInput(userInput)
for i := 0; i < len(questions); i++ {
fmt.Println(questions[i].Text)
fmt.Print("Enter answer ")
select {
case userAnswer := <-userInput:
if userAnswer == questions[i].Answer {
fmt.Println("Correct answer:", userAnswer)
points++
} else {
fmt.Println("Wrong answer")
}
case <-time.After(5 * time.Second):
fmt.Println("\n Time is over!")
}
}
}
您可能需要添加一些其他邏輯或處理程序,以在某些時候終止輸入讀取goroutine,這取決於程序的實際生命周期,但這是另一個問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.