英文:
timeout for input in terminal go application
问题
我正在尝试制作一个终端golang
应用程序,用户有4秒的时间输入内容。如果他输入得更快,就打印结果并再次要求他在4秒内输入。
如果用户在4秒内没有返回输入,程序必须写入time out
并再次要求输入。
我的代码可以实现这个功能,但只能执行一次。在第一次超时后,即使用户在4秒内输入,也不会返回任何结果。我无法弄清楚为什么会这样。
代码如下:
package main
import (
"bufio"
"fmt"
"log"
"os"
"time"
)
var (
result string
err error
)
func getInput(input chan string) {
in := bufio.NewReader(os.Stdin)
result, err := in.ReadString('\n')
if err != nil {
log.Fatal(err)
}
input <- result
}
func main() {
for {
fmt.Println("请输入内容:")
input := make(chan string, 1)
go getInput(input)
select {
case i := <-input:
fmt.Println("结果:")
fmt.Println(i)
case <-time.After(4000 * time.Millisecond):
fmt.Println("超时")
}
}
}
输出结果:
请输入内容:
123
结果:
123
请输入内容:
2
结果:
2
请输入内容:
超时
请输入内容:
2
超时
请输入内容:
超时
请输入内容:
希望这可以帮助到你。
英文:
I am trying to make a terminal golang
application, where a user has 4 seconds to input something. If he inputted something faster, print result and ask him input again for 4 seconds.
If a user will not return input in 4 seconds, the program must write time out
and ask him input again.
My code does this, but only once. After the first timeout
it won't return any result even if a user was faster that 4 seconds. I cannot figure out why this is so.
The code
package main
import (
"bufio"
"fmt"
"log"
"os"
"time"
)
var (
result string
err error
)
func getInput(input chan string) {
in := bufio.NewReader(os.Stdin)
result, err := in.ReadString('\n')
if err != nil {
log.Fatal(err)
}
input <- result
}
func main() {
for {
fmt.Println("input something")
input := make(chan string, 1)
go getInput(input)
select {
case i := <-input:
fmt.Println("result")
fmt.Println(i)
case <-time.After(4000 * time.Millisecond):
fmt.Println("timed out")
}
}
}
The output:
input something
123
result
123
input something
2
result
2
input something
timed out
input something
2
timed out
input something
timed out
input something
答案1
得分: 3
问题与您获取用户输入的方式有关。在超时时,您会生成一个新的go例程来请求输入,但之前生成的旧例程仍然存在,它会获取输入并将其发送到一个没有人再监听的通道中。
将其更改为以下内容将解决问题:
func getInput(input chan string) {
for {
in := bufio.NewReader(os.Stdin)
result, err := in.ReadString('\n')
if err != nil {
log.Fatal(err)
}
input <- result
}
}
func main() {
input := make(chan string, 1)
go getInput(input)
for {
fmt.Println("请输入:")
select {
case i := <-input:
fmt.Println("结果:")
fmt.Println(i)
case <-time.After(4000 * time.Millisecond):
fmt.Println("超时")
}
}
}
请注意,这只是代码的翻译部分,不包括任何其他内容。
英文:
The problem has to do with the way you're getting the user's input. On a timeout you spawn a new go routine asking for input, but the old one that you had spawned previously is still there grabbing input and sending it to a channel that no one is listening to any more.
Changing it to something like this would fix the problem:
func getInput(input chan string) {
for {
in := bufio.NewReader(os.Stdin)
result, err := in.ReadString('\n')
if err != nil {
log.Fatal(err)
}
input <- result
}
}
func main() {
input := make(chan string, 1)
go getInput(input)
for {
fmt.Println("input something")
select {
case i := <-input:
fmt.Println("result")
fmt.Println(i)
case <-time.After(4000 * time.Millisecond):
fmt.Println("timed out")
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论