Learn Go | Tutorial 4: Listening to the User
- 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)
You have built a list of hardcoded tasks. Now, you will make the program interactive by allowing the user to type in a new task.
Right now, your tasks are stuck inside the code. If you want to add “Call Mom”, you have to edit main.go and recompile. That is terrible.
The Need is to pause the program, wait for you to type something, and then capture that text into a variable.
In Go, the standard tool for reading full lines of text (like “Buy milk and eggs”) is the bufio (Buffered I/O) package.
Step 1: Import the new tools 🔗
You need two new standard libraries:
bufio: To create a “Scanner” that reads input.os: To access the operating system’s standard input (your keyboard).
Update your imports in main.go. Note that when you have multiple imports, you wrap them in parentheses:
package main
import (
"bufio"
"fmt"
"os"
)
Step 2: The Scanner setup 🔗
We will delete our hardcoded list and ask the user for a single new task instead.
Inside main(), replace your tasks := []string{...} block with this logic:
- Print a prompt so the user knows what to do.
- Create a Scanner that watches
os.Stdin(Standard Input). - Tell the scanner to Scan (read until the next line break).
- Extract the Text it found.
Here is the code to replace your old tasks slice:
// ... keep appName, version, status variables ...
fmt.Printf("%s %s: Status = %s\n", appName, version, status)
// 1. Prompt the user
fmt.Print("Enter a new task: ")
// 2. Create the scanner
scanner := bufio.NewScanner(os.Stdin)
// 3. Scan for input (this pauses the program until you hit Enter)
scanner.Scan()
// 4. Get the text
task := scanner.Text()
// 5. Add it to a slice (we'll start with an empty one)
tasks := []string{task}
fmt.Println("Your list:", tasks)
Why not fmt.Scan?
You might see tutorials using fmt.Scanln(&task). That function is bad at reading sentences because it stops at the first space. If you typed “Buy Milk”, fmt.Scan would only grab “Buy”. bufio.Scanner grabs the whole line.
Step 3: Run it 🔗
Save the file and run:
go run main.go
Output:
Go-Getter v0.1: Status = Online
Enter a new task: Walk the dog
Your list: [Walk the dog]
Step 4: The problem with one task 🔗
We can now read one task. But a to-do list with one item isn’t a list. We need to let the user enter as many as they want.
To do this, we need a loop that keeps asking “More?” until the user says “No”.
Modify your code to wrap the scanning logic in a for loop.
// Start with an empty list
tasks := []string{}
reader := bufio.NewScanner(os.Stdin)
fmt.Println("Enter tasks (leave empty and press Enter to finish):")
for {
fmt.Print("> ") // A simple prompt
reader.Scan()
text := reader.Text()
// If the user typed nothing (length is 0), stop the loop
if len(text) == 0 {
break
}
// Add the new task to the list
tasks = append(tasks, text)
}
fmt.Println("Final list:", tasks)
New Concepts:
tasks := []string{}: Creates an empty slice (0 items).for { ... }: An infinite loop. It runs forever until we manuallybreakout.len(text) == 0: Checks if the string is empty.append(tasks, text): This is how slices grow. It takes your old list, adds the new item to the end, and returns a new list.
Complete main.go for Tutorial 4 🔗
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
appName := "Go-Getter"
version := "v0.1"
fmt.Printf("%s %s is ready.\n", appName, version)
tasks := []string{}
scanner := bufio.NewScanner(os.Stdin)
fmt.Println("Enter tasks (press Enter on an empty line to finish):")
for {
fmt.Print("> ")
scanner.Scan()
input := scanner.Text()
if len(input) == 0 {
break
}
tasks = append(tasks, input)
}
fmt.Println("Your To-Do List:")
for i, task := range tasks {
fmt.Printf("%d. %s\n", i+1, task)
}
}
The Next Wall:
We can add tasks, but we can’t delete them, mark them as done, or save them. Right now, every time you run the program, you start from zero.
In Tutorial 5, we will build a “Command Loop” (a Menu) so the user can choose actions like add, list, or quit instead of just blindly adding tasks. This will require if/else logic.
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)