Step 1 of 5 · Reading · ~4 min
Learn
Control Flow
Loops with for
Go has exactly one loop keyword. There is no while, no do, no until — for covers every repetition you will ever write, and by the end of this lesson you can pick the right one of its four shapes and land the counter boundary that decides how many times the body runs.
The three-part form
Three clauses separated by semicolons: init (k := 2, runs once), condition (k <= 5, tested before every pass) and post (k++, run after every pass). No parentheses around them, and the braces are mandatory even for a one-line body. k is scoped to the loop; after the closing brace the name does not exist.
Traced pass by pass:
| pass | k | product afterwards |
|---|---|---|
| 1 | 2 | 2 |
| 2 | 3 | 6 |
| 3 | 4 | 24 |
| 4 | 5 | 120 |
| — | 6 | condition false, loop exits |
The table makes two things visible. product is declared before the loop, so it survives every pass and carries the result out; a variable declared between the braces is created fresh on each pass and discarded at the closing brace. And the post clause still runs after the last useful pass, so the loop exits with k sitting one step past the bound.
The boundary: < versus <=
Change the condition to k <= 20 and the same loop runs 11 times. Neither is more correct; you choose the one that matches the range you actually mean. Because getting it wrong costs exactly one pass, the answer comes out close — and close is a failed test, not a near miss.
Condition only: Go's while
Drop the init and the post and you have a while. Note the result: the condition is only tested between passes, so the pass that started at 81 ran to completion and left size at 243, well past 100. A loop never stops in the middle of its body.
No condition: the infinite loop
A bare for repeats until something inside it says otherwise: break leaves the innermost loop, return leaves the whole function, and continue skips the rest of this pass and jumps straight to the next one. This is the shape of every server and every worker you will ever read.
range
range walks a collection and hands you index and element. The collection below is a slice,
an ordered list of values written []int{7, 4, 9}; the Slices lesson covers building and changing
them, and here it is only something to walk:
The _ (blank identifier) is needed because Go's unused-variable rule applies here too; _ is how you say "I know, and I don't want it". Over a string, range decodes runes, as you saw in String Basics.
One subtlety worth planting now: val is a copy of the element. Assigning to val changes nothing in the slice — scores[idx] = val * 2 does. When a loop "isn't changing anything", this is almost always why.
Common mistakes
- Declaring the running variable inside the braces. It is created fresh on every pass, so it never accumulates: the program prints whatever the last pass alone put in it, which for a summing loop is the final term rather than the sum.
- Stopping one short. Writing
<where the upper value itself belongs in the range drops exactly one term, so the printed number is short by that amount and looks almost right. - Printing inside the loop. You get one line per pass instead of one line in total. Output is compared whole, so the extra lines fail even when the last line is correct.
- Assigning to the range variable.
val = val * 2insidefor _, val := range scoresedits a copy and leavesscoresuntouched.
Your exercise
Read N and print the sum of every integer from 1 through N. The starter reads the value and prints a placeholder, so it compiles and runs from the first keystroke — your job is to replace that placeholder with a genuinely accumulated total. The mistake that fails this task most often is the boundary: N itself belongs in the sum.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…