I have a very simple command line utility and at the end of it I'm waiting for a user to hit the enter key to end the program:
fmt.Scanf("\n") // wait for hitting the enter key to end the program
Now I want to change it and if the enter key hasn't been hit for some time, I want to cancel Scanf
and do something else. Is it possible to cancel waiting for user's input?
You can simply create a channel and launch a goroutine which does the fmt.Scanf("\n")
and then writes something to the channel. Then select
between that channel and time.After(3 * time.Second)
.
Here's a solution:
package main
import (
"fmt"
"time"
"os"
)
func main() {
// Rest of the program...
ch := make(chan int)
go func() {
fmt.Scanf("\n")
ch <- 1
}()
select {
case <-ch:
fmt.Println("Exiting.")
os.Exit(0)
case <-time.After(3 * time.Second):
fmt.Println("Timed out, exiting.")
}
}
NOTE: as pointed out by @Fabian and @YotKay in the comments, this will "leak" a goroutine (meaning it will remain running until the process exits) if the timeout expires and the user does not enter anything. This is still fine in a situation in which you have to either wait for input or exit the program, but not advisable in other cases, since it's not possible to "cancel" goroutines from the outside.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With