3

Is it okay to use os.stdin as a Reader in a Goroutine? Basically what I would like to accomplish is to enable the user to enter a message without blocking the main thread.

Example:

go func() {
    for {
        consolereader := bufio.NewReader(os.Stdin)

        input, err := consolereader.ReadString('\n') // this will prompt the user for input

        if err != nil {
             fmt.Println(err)
             os.Exit(1)
        }

        fmt.Println(input)
    }
}()
linirod
  • 371
  • 3
  • 9

1 Answers1

2

Yes, this is perfectly fine. So long as this is the only goroutine that is interacting with os.Stdin, everything will work properly.

By the way, you may want to use bufio.Scanner - it's a bit nicer to work with than bufio.Reader:

go func() {
    consolescanner := bufio.NewScanner(os.Stdin)

    // by default, bufio.Scanner scans newline-separated lines
    for consolescanner.Scan() {
        input := consolescanner.Text()
        fmt.Println(input)
    }

    // check once at the end to see if any errors
    // were encountered (the Scan() method will
    // return false as soon as an error is encountered) 
    if err := consolescanner.Err(); err != nil {
         fmt.Println(err)
         os.Exit(1)
    }
}()
joshlf
  • 21,822
  • 11
  • 69
  • 96
  • I would like to thank you for your quick and detailed response/example :) I'm new to Go and I'm still experimenting. I'll try bufio.Scanner tonight. Again thanks for your feedback! – linirod Nov 17 '15 at 21:37
  • I used your code to pull an integer from the user input in the command line, but `input.Text()` returns a string. I thought it would return an `int`, since a number was entered into the command line? I'll include my code: `input := bufio.NewScanner(os.Stdin) var t TimeOfDay for input.Scan() { number :=input.Text() t = append(t, timeFeatures[number - 1]) }` – Azurespot Nov 22 '19 at 03:58
  • You have to keep in mind that the types of variables are decided at compile time, long before you've actually provided input to a running program. The compiler has no way of knowing that you're going to provide a number in the future, so it has no choice but to pick a single type for all input - in this case, `string` is the only type that is correct for all inputs. If you happen to know that you are expecting an integer, you could perform an explicit conversion on the string using something like [`strconv.Atoi`](https://golang.org/pkg/strconv/#Atoi). – joshlf Nov 23 '19 at 04:37