Checkpoint: Go Basics
You've learned data types, control flow, loops, arrays, slices, maps and pointers — let's combine them. This checkpoint has no new syntax. Instead you'll prove the pieces fit together by building one realistic program that reads a slice of structs, tallies with a map, and loops with range — then test yourself with a short quiz.
Learn Checkpoint: Go Basics in our free Go course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick recall.
Part of the free Go course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You've Learned So Far
Everything in this checkpoint draws on the seven lessons before it. Here's the toolkit you're now carrying:
Topic
Key idea
You can now…
Data types & iota
Sized numbers, runes, enums
const ( A = iota )
Control flow
Branch with if / switch
if x > 0 { } switch { }
for & range
Go's one loop, any collection
for i, v := range s
Arrays
Fixed length, value semantics
[3]int{1,2,3}
Slices
Growable, shared backing
s = append(s, x)
Maps
Key/value, comma-ok, tally
counts[k]++
Pointers
Share & mutate without copying
p := &x; *p = 9
🛠️ Build Challenge: Order Summary
One small program ties together a struct , a slice , a map , a range loop , integer-to-float conversion, and key sorting. Start from the scaffold below. The data and the Item struct are given — your job is the loop in the middle and the printing at the end.
Your starting point
Fill in the loop and the output. Work through the four numbered steps in the comments — attempt it before peeking.
Stuck? Reveal the worked solution
The whole thing fits in one pass over the slice. Notice three deliberate choices: a single range loop does both the money total and the tally; float64(grandTotal)/100 avoids integer division so the pounds print correctly; and the map keys are copied into a slice and sort.Strings 'd because map order is random.
- • Struct + slice: []Item holds the line items by value.
- • One range pass: accumulates grandTotal and fills counts together.
- • Conversion: float64(grandTotal)/100 turns 1249 pence into £12.49.
- • Deterministic output: sorting the keys makes the lines print in a stable, alphabetical order.
⏱ Timed Quiz
📝 Checkpoint Quiz
Answer each in your head, then reveal it. Aim for at least 5 out of 6 before moving on.
1. What does counts[k]++ do when k isn't yet in the map?
It reads the missing key as the zero value 0 , adds 1, and stores 1. No need to check for the key first — this is the standard tally idiom.
2. Why is 7 / 2 equal to 3 in Go, and how do you get 3.5 ?
Both operands are int , so Go does integer division and truncates. Convert first: float64(7) / 2 gives 3.5 .
3. After b := a; b[0] = 9 , when does a[0] change — for an array vs a slice?
For an array , a is unchanged (arrays are copied). For a slice , a[0] becomes 9 too, because both slices share the same backing array.
4. Why must you write s = append(s, x) and not just append(s, x) ?
append may allocate a new backing array and returns the resulting slice. If you drop the assignment, your new element can be lost.
5. How do you make a function change the caller's variable?
Take a pointer parameter ( func f(n *int) ), call it with the address ( f(&x) ), and write through it ( *n = ... ). Passing a plain value only edits a copy.
6. Why might two runs of a program print map entries in a different order?
Go deliberately randomizes map iteration order so code never relies on it. For stable output, collect the keys into a slice and sort them first.
Frequently Asked Questions
Q: I couldn't finish the build challenge — should I move on?
Revisit the specific lesson the sticking point came from (slices, maps, or pointers) and try again. Checkpoints are diagnostic: a gap here is exactly what they're meant to surface before it compounds.
No — just remember the pattern : collect keys into a slice, sort the slice, then range it. You can always look up the exact function name in the docs.
Interfaces — Go's way of describing behaviour without inheritance. They build directly on the struct and method ideas you'll see in the very next lesson on methods.
🎉 Checkpoint Complete!
- ✅ Combined a struct, slice, map, range loop and conversion in one program
- ✅ Used the tally idiom counts[k]++ on real data
- ✅ Avoided integer division with float64(x)/100
- ✅ Produced deterministic output by sorting map keys
- ✅ Reviewed value vs reference semantics and pointer mutation in the quiz
- ✅ Next lesson: Methods — attaching behaviour to your types
Practice quiz
What does counts[k]++ do when the key k is not yet present in the map?
- It panics with a nil map error
- It does nothing because the key is absent
- It reads the missing key as 0, adds 1, and stores 1
- It returns false
Answer: It reads the missing key as 0, adds 1, and stores 1. A missing key reads as the value type's zero value (0 for int), so counts[k]++ stores 1 — the standard tally idiom.
In Go, what is the result of the integer expression 7 / 2?
- 3
- 3.5
- 4
- a compile error
Answer: 3. Both operands are int, so Go performs integer division and truncates toward zero, giving 3.
How do you get 3.5 from dividing 7 by 2 in Go?
- Use 7 // 2
- Add a decimal: 7.0 is not allowed, so it cannot be done
- Use math.Div(7, 2)
- Convert first: float64(7) / 2
Answer: Convert first: float64(7) / 2. Converting an operand to float64 makes the division floating-point, yielding 3.5.
After b := a; b[0] = 9, when does a[0] also become 9?
- When a is an array
- When a is a slice (both share the same backing array)
- Never — assignment always copies
- Only for maps
Answer: When a is a slice (both share the same backing array). Arrays are copied on assignment, but a slice header copy still points at the same backing array, so the change is shared.
Why must you write s = append(s, x) rather than just append(s, x)?
- append may allocate a new backing array and returns the resulting slice, which you must capture
- append is not a real function
- Go forbids ignoring return values
- It prevents the element from being garbage collected
Answer: append may allocate a new backing array and returns the resulting slice, which you must capture. append can reallocate and returns the (possibly new) slice; dropping the assignment can lose your appended element.
How do you make a function modify the caller's variable?
- Return the new value and ignore it
- Declare the variable as global
- Pass a pointer (func f(n *int)), call f(&x), and write through it with *n = ...
- Mark the parameter with the mutable keyword
Answer: Pass a pointer (func f(n *int)), call f(&x), and write through it with *n = .... Passing a pointer and writing through *n edits the caller's variable; passing a value only edits a local copy.
Why might two runs of the same program print map entries in different orders?
- Maps store keys by insertion time, which varies
- Go deliberately randomizes map iteration order so code never relies on it
- The garbage collector reshuffles maps
- It is undefined behavior and a bug
Answer: Go deliberately randomizes map iteration order so code never relies on it. Go randomizes map iteration order on purpose; collect keys into a slice and sort them for stable output.
Using the comma-ok form v, ok := m[k], what is ok?
- true only if the value is non-zero
- always true for a non-nil map
- the number of entries in the map
- true only if the key exists in the map
Answer: true only if the key exists in the map. ok reports whether the key is present, distinguishing a missing key from a stored zero value.
What is the difference between an array and a slice in Go?
- Arrays grow automatically; slices have fixed length
- An array has a fixed length that is part of its type; a slice is a growable view over a backing array
- They are identical aliases
- Slices can only hold strings
Answer: An array has a fixed length that is part of its type; a slice is a growable view over a backing array. [3]int and [4]int are distinct array types with fixed length; a slice []int is a dynamic, growable view.
Which loop keyword does Go provide for iterating over slices and maps?
- foreach
- while
- for ... range
- iterate
Answer: for ... range. Go has a single loop keyword, for, and the for ... range form iterates collections.
Continue this course
- Previous: Pointers
- Next: Methods (value vs pointer receivers)