Video Coming Soon...
9: Flow Control: for
WARNING This exercise is in DRAFT status, so there may be errors. If you find any, please email me at help@learncodethehardway.com so I can fix them.
I'm going to give you a tiny little puzzle and I want you to figure out how to use it. In Go you can do something called a jump with the goto
keyword. Code that jumps looks like this:
loop:
fmt.Println("loop!")
goto loop
When you do this go skips over the loop:
, runs the fmt.Println
, then when it reaches the goto loop
it will jump back to the first line with loop:
and do it again.
In this case the code will loop forever but you normally don't want that. You'll want to only loop a certain number of times.
Here's the puzzle:
- You know how to use an
if-statement
to run a block of code based on a variable's value. - You also know how to use
goto
to jump to a previous line of code (or later). - You can also do math with variables, such as add 1 to a number with
i = 1 + 1
or the shorteri++
. - Can you figure out how to loop only 10 times using only a variable,
goto
, andif
?
Try to figure it out before seeing my solution.
Solution
Here's my solution, and you can actually do this a few different ways:
View Source file ex09a/main.go Only
package main
import (
"fmt"
)
func main() {
i := 0
loop:
fmt.Println("loop", i)
i++
if i < 10 { goto loop }
fmt.Println("Loop ended")
}
While this does work, it really really sucks when you get serious about programming. It's better to use the built-in looping construct that Go has named for
.
Using for
Instead
Go's for
loop is unique in that it's the only looping construct in the language. Other languages have 2 or 3, sometimes 4 ways to do looping, but Go went for the simpler approach and made their for
keyword do it all. The simplest use of for
is to loop forever:
for {
fmt.Println("Spin me right round baby")
}
That will run until you kill your program (using CTRL-c on most computers). This use does come up in long running programs like servers and games, but the more common use is to loop only while some condition is true:
i := 0
for i < 10 {
i++
fmt.Println("looped", i, "times")
}
This is similar to what you did with if
and goto
, but this form still has a problem because you might forget one of the lines like this:
i := 0
for i < 10 {
fmt.Println("Spin me right roung baby")
}
The loop would never end because we forgot the i++
line. A better way is to combine all of the required operations on the for line so you don't forget:
for i := 0; i < 10; i++ {
fmt.Println("looped", i, "times")
}
This version of for
is almost the same as the one with i := 0
and i++
on separate lines, but it far easier to get right.
NOTE Back in the old days of computing this was a huge problem because computers were insanely expensive and you were charged for your time to use them. This means if you wrote a program that looped forever you could kill off your alloted time to use the computer. It's similar to people today getting a $100k bill from Vercel because their website went viral for one day. If you wrote a bad loop you'd be out of a lot of money, so languages eventually evolved to make it easier to figure out if a loop would end.
The Code
Here's the code for this exercise. As usual type it all in, but not all at once. Remember if you type it all at once and only compile it one time then you have to do it all over again.
View Source file ex09b/main.go Only
package main
import (
"fmt"
)
func main() {
// first style loops like an if-statement
i := 0
for i < 10 {
fmt.Println("loop", i)
i++
}
fmt.Println("------ first loop ended")
// second style does all of that for you
for i := 0; i < 10; i++ {
fmt.Println("loop", i)
}
fmt.Println("------ second loop ended")
// third style loops forever, uncomment this to see
/*
for {
fmt.Println("Noooooooooooo")
}
*/
}
The Breakdown
As before I'm not going to explain every line, just the new ones.
i := 0
-- This creates ani
variable starting at 0.for i < 10 {
-- This starts afor
that will go as long asi
is less than10
.fmt.Println("loop", i)
-- Print out the value ofi
at this point in the loop.i++
-- Incrementi
by 1.}
-- End of the block, go back to thefor
, run the test again, and if it passes then run the block again. If the test DOES NOT pass then continue.fmt.Println("------ first loop ended")
-- We're out of the firstfor-loop
.for i := 0; i < 10; i++ {
-- Start afor-loop
with the better syntax that does all three things.fmt.Println("loop", i)
-- Print out the value ofi
.}
-- End of the block, and just like before either repeat the block or continue depending on the result of thefor
test.fmt.Println("------ second loop ended")
-- Loop ended./*
-- This starts a multi-line comment. Delete this and its matching*/
to see the forever loop work.for {
-- This loops forever.fmt.Println("Noooooooooooo")
-- Print that.}
-- End of block, repeat.*/
-- Delete this to see the forever loop.
The Practice
Yes, once again I'm going to give you our 3 step process to become a great programmer:
- Break It -- You need to learn what error messages mean and what causes them, so break this code on purpose in as many ways as possible.
- Change It -- Try to craft as many different loops as possible. Take this as a game and try to make the most horrendous contraption imaginable. Can you throw some
goto
in the middle of a loop with anif
that goes to random places? - Remake It -- Write up a description of the code, hide or delete this, then try to recreate it using the process from Exercise 04: How to Write Code. Try to do this from memory as much as possible.
Study Drills
- It's important to learn how you can combine the things you've learned in new ways. Try to write one program that combines everything so far, even if it doesn't really make sense.
- Can you figure out how to use a loop to calculate a fibonacci sequence.
Register for Learn Go the Hard Way
Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.