Learn Go | Tutorial 5: Making Choices (The Command Loop)
- Part 1: Learn Go | Tutorial 1 (The Handshake): Your First Go Program
- Part 2: Learn Go | Tutorial 2: Storing a Thought (Variables)
- Part 3: Learn Go | Tutorial 3: The Grocery List Problem
- Part 4: Learn Go | Tutorial 4: Listening to the User
- Part 5: Learn Go | Tutorial 5: Making Choices (The Command Loop)
- Part 6: Learn Go | Tutorial 6: The Memory Loss Issue (File Persistence)
This tutorial transforms your simple “add-only” loop into a real interactive menu system.
Right now, your program is a one-trick pony: it launches, forces you to add tasks, and then quits. You have no control. You can’t just view the list without adding something, and you can’t exit gracefully without finishing your additions.
The Need is logic. You need the program to ask, “What do you want to do?” and then execute different code based on your answer.
We will introduce the switch statement and restructure our “Game Loop”.
Step 1: The Infinite Loop 🔗
We need a loop that runs forever until the user explicitly says “quit”.
Inside this loop, we will:
- Print a menu.
- Ask for a command.
- specific code based on that command.
Clear your main function logic (keep the variables and scanner setup) and structure it like this:
func main() {
// ... setup variables ...
tasks := []string{}
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Go-Getter v0.1 started.")
fmt.Println("Commands: add, list, quit")
for {
fmt.Print("\nCommand: ") // \n adds a blank line before the prompt
scanner.Scan()
command := scanner.Text()
// logic will go here...
}
}
Step 2: The Switch Statement 🔗
You could use if command == "add" { ... } else if command == "list" { ... }, but that gets messy fast.
Go has a clean switch statement for this exact scenario. It takes a variable and compares it against multiple “cases”.
Add this inside your for loop:
switch command {
case "add":
fmt.Print("Enter task: ")
scanner.Scan()
newTask := scanner.Text()
tasks = append(tasks, newTask)
fmt.Println("Task added.")
case "list":
fmt.Println("--- Your Tasks ---")
for i, task := range tasks {
fmt.Printf("%d. %s\n", i+1, task)
}
case "quit":
fmt.Println("Bye!")
return // This exits the entire function, stopping the loop
default:
fmt.Println("Unknown command. Try 'add', 'list', or 'quit'.")
}
New Concepts:
switch command { ... }: Evaluatescommandonce.case "value":: Ifcommandmatches this value, run the code below it. No need for curly braces{}per case.return: Instantly exits themainfunction, which terminates the program.default: Runs if no other case matches (like anelse).
Step 3: Complete Code for Tutorial 5 🔗
Here is how your main.go should look. It is now a fully functioning, interactive CLI tool.
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
tasks := []string{}
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Go-Getter v0.1")
fmt.Println("---------------------")
fmt.Println("Available commands: 'add', 'list', 'quit'")
for {
fmt.Print("\nCommand: ")
scanner.Scan()
command := scanner.Text()
switch command {
case "add":
fmt.Print("Enter new task: ")
scanner.Scan()
task := scanner.Text()
// Basic validation: don't add empty tasks
if len(task) == 0 {
fmt.Println("Task cannot be empty.")
} else {
tasks = append(tasks, task)
fmt.Println("Saved.")
}
case "list":
if len(tasks) == 0 {
fmt.Println("No tasks yet.")
} else {
for i, task := range tasks {
fmt.Printf("%d. %s\n", i+1, task)
}
}
case "quit":
fmt.Println("Exiting Go-Getter...")
return
default:
fmt.Println("Unknown command.")
}
}
}
Step 4: Test it 🔗
Run go run main.go.
- Type
list. It should say “No tasks yet.” - Type
add, thenBuy Milk. - Type
add, thenWalk Dog. - Type
listagain. You should see both items numbered. - Type
dance. It should say “Unknown command.” - Type
quit. The program stops.
The Final Wall:
You have a working program! But restart it.
Everything is gone.
The memory is wiped every time you quit. This is useless for a real to-do list.
In Tutorial 6 (The Final Step), we will solve the “Memory Loss Issue”. We will learn how to write this list to a file on your hard drive before quitting, and read it back when the program starts. This will introduce structs (maybe) and File I/O.
I hope you enjoyed reading this post as much as I enjoyed writing it. If you know a person who can benefit from this information, send them a link of this post. If you want to get notified about new posts, follow me on YouTube , Twitter (x) , LinkedIn , and GitHub .
- Part 1: Learn Go | Tutorial 1 (The Handshake): Your First Go Program
- Part 2: Learn Go | Tutorial 2: Storing a Thought (Variables)
- Part 3: Learn Go | Tutorial 3: The Grocery List Problem
- Part 4: Learn Go | Tutorial 4: Listening to the User
- Part 5: Learn Go | Tutorial 5: Making Choices (The Command Loop)
- Part 6: Learn Go | Tutorial 6: The Memory Loss Issue (File Persistence)