Last active
April 16, 2023 03:03
-
-
Save albrow/5882501 to your computer and use it in GitHub Desktop.
Go (golang): How to ask for user confirmation via command line
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import ( | |
"fmt" | |
"log" | |
"os" | |
"sort" | |
) | |
// askForConfirmation uses Scanln to parse user input. A user must type in "yes" or "no" and | |
// then press enter. It has fuzzy matching, so "y", "Y", "yes", "YES", and "Yes" all count as | |
// confirmations. If the input is not recognized, it will ask again. The function does not return | |
// until it gets a valid response from the user. Typically, you should use fmt to print out a question | |
// before calling askForConfirmation. E.g. fmt.Println("WARNING: Are you sure? (yes/no)") | |
func askForConfirmation() bool { | |
var response string | |
_, err := fmt.Scanln(&response) | |
if err != nil { | |
log.Fatal(err) | |
} | |
okayResponses := []string{"y", "Y", "yes", "Yes", "YES"} | |
nokayResponses := []string{"n", "N", "no", "No", "NO"} | |
if containsString(okayResponses, response) { | |
return true | |
} else if containsString(nokayResponses, response) { | |
return false | |
} else { | |
fmt.Println("Please type yes or no and then press enter:") | |
return askForConfirmation() | |
} | |
} | |
// You might want to put the following two functions in a separate utility package. | |
// posString returns the first index of element in slice. | |
// If slice does not contain element, returns -1. | |
func posString(slice []string, element string) int { | |
for index, elem := range slice { | |
if elem == element { | |
return index | |
} | |
} | |
return -1 | |
} | |
// containsString returns true iff slice contains element | |
func containsString(slice []string, element string) bool { | |
return !(posString(slice, element) == -1) | |
} |
^^
This is a better way to do the same.
@r0l1 404
@r0l1 Necropost, but this Gist is still better. It uses fmt.Scanln
instead of buffo.NewReader
. Yours could read too much from stdin and discard input.
Actually @albrow, I think you could combine your last two functions like so:
func containsString(slice []string, element string) bool {
for _, elem := range slice {
if elem == element {
return true
}
}
return false
}
Or even better
func askForConfirmation() bool {
var response string
_, err := fmt.Scanln(&response)
if err != nil {
log.Fatal(err)
}
switch strings.ToLower(response) {
case "y", "yes":
return true
case "n", "no":
return false
default:
fmt.Println("I'm sorry but I didn't get what you meant, please type (y)es or (n)o and then press enter:")
return askForConfirmation()
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can be simplified by lowercasing the first character of the string and comparing to either "y" or "n".