02 — Variables, types, control flow, and functions
Goal
Use Go's basic types, conditionals, loops, and multiple return values.
Step 1: Add a small domain helper
Replace main.go with:
package main
import "fmt"
func normalizeTitle(title string) (string, error) {
if title == "" {
return "", fmt.Errorf("title is required")
}
return title, nil
}
func main() {
titles := []string{"Write proposal", "", "Review pull request"}
for index, title := range titles {
normalized, err := normalizeTitle(title)
if err != nil {
fmt.Printf("task %d: %v\n", index+1, err)
continue
}
fmt.Printf("task %d: %s\n", index+1, normalized)
}
}
Run gofmt -w main.go then go run .. The empty title produces an error line; the other two are printed as tasks.
Step 2: Read the syntax
title string is a parameter. (string, error) means the function returns two values. := declares and initializes a local variable. if chooses a branch. for range iterates over a slice and provides an index and value. continue skips to the next iteration. Go has no while keyword; for handles looping.
Common built-in types include string, bool, int, int64, and float64. A variable declared with var count int starts at its zero value (0). A string starts as "", and a bool starts as false.
Go makes errors explicit in a function's return values. A function that returns (string, error) gives its caller both the useful result and a description of failure. nil means the error is absent. The caller must decide what to do with a non-nil error; Go does not throw it automatically. This pattern is used throughout the course and inside gRPC handlers.
The loop uses range, which produces values from a collection. The blank identifier _ is used when a returned value is intentionally ignored. continue is useful when one bad input should not prevent processing later items; return would end the whole function.
Step 3: Add a switch
Add this function above main:
func statusLabel(status string) string {
switch status {
case "TODO":
return "Waiting"
case "IN_PROGRESS":
return "Under way"
case "DONE":
return "Complete"
default:
return "Unknown"
}
}
Call it from main and print the result for "DONE".
switch selects one branch based on a value. Go stops at the matching case automatically, so an explicit break is not needed. A default branch makes unknown input visible instead of silently treating it as a known status.
Step 4: Check your work
gofmt -w main.go
go run .
go vet ./...
Checkpoint
Write isValidTitle(title string) bool, which returns true only if the title is non-empty. Then change normalizeTitle to use it.
Practice
Make statusLabel handle lowercase input. Hint: use strings.ToUpper and import the strings package.