Start learning free

LESSON 108 OF 338 · FOR LOOPS - LOOPING OVER ARRAYS

Fixing a Buggy for Loop in Go: Using the Loop Variable

Practice Read the full explanation

Inside the code editor we've tried to write a for loop that prints a tailored message about every language in the languages array.

So when we ran the code, we expected it to print:

I think Python is cool!
I think Java is cool!
I think JavaScript is cool!

but it seems like we made some mistakes because when we run our code, it produces this output:

I think language is cool!
I think language is cool!
I think language is cool!

Assignment:

Your task is to fix our loop such that it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    GO · FOR LOOPS - LOOPING OVER ARRAYS

    Buggy Code For Loops 2 in Go, explained

    What the code is supposed to do

    The loop should print a tailored sentence for every language in the languages slice:

    I think Python is cool!
    I think Java is cool!
    I think JavaScript is cool!
    

    The starting code is this:

    languages := []string{"Python", "Java", "JavaScript"}
    
    for _, language := range languages {
        fmt.Println("I think language is cool!")
    }
    

    What goes wrong

    Go refuses to compile it and reports language declared and not used. The loop declares the variable language, but the body never uses it. Inside the quotes, language is not a variable. It is five ordinary letters that belong to the text. A string literal is copied exactly as written, so the same sentence would be printed on every pass if Go allowed it to run.

    Both symptoms have one cause: the sentence is constant, and the part that should change from pass to pass is hard-coded as text.

    Fixing it step by step

    1. Split the sentence. The text before the language is "I think ", with a trailing space. The text after it is " is cool!", with a leading space.
    2. Put the variable between them. Join the three pieces with the + operator, which concatenates strings in Go.
    3. Keep the spaces inside the quotes. Concatenation adds nothing of its own, so a missing space gives I think Pythonis cool!.

    The fixed code in Go

    languages := []string{"Python", "Java", "JavaScript"}
    
    for _, language := range languages {
        fmt.Println("I think " + language + " is cool!")
    }
    

    Now the loop variable appears in the body, so the compiler is satisfied, and its value changes on each pass: first Python, then Java, then JavaScript. The index is discarded with _, since the message doesn't need it.

    Concatenation is not the only option. fmt.Println("I think", language, "is cool!") also works, because Println puts a space between its arguments. fmt.Printf("I think %s is cool!\n", language) fills in a placeholder. The + version is the one this lesson uses.

    Why Go is strict here

    Many languages let the original code run and print the wrong sentence three times, leaving you to spot the bug in the output. Go stops earlier. An unused variable is almost always a sign that you meant to use it, and here the compiler's complaint points straight at the cause. When you see declared and not used inside a loop, ask what the variable was supposed to change.

    The same habit helps with the other direction. If a loop prints identical lines, check whether the body reads the loop variable at all.

    Common mistakes

    • Quoting the variable. Any name inside quotes is just text, in every position of a string.
    • Missing spaces. The pieces "I think" and "is cool!" without the spaces print the words glued to the language.
    • Adding a non-string with +. The loop variable is a string here, so the join works. Adding an int to a string with + is a compile error (mismatched types), so convert it first with strconv.Itoa or use Printf.
    • Hiding the error with _ = language. That compiles, but the output is still wrong.

    Trying variations

    To see the loop variable change, add the index to the message. for i, language := range languages gives you i as well, and strconv.Itoa(i+1) + ". " + language prints 1. Python, 2. Java and 3. JavaScript. Experiment with the wording in the editor, and notice that each change either uses the variable or fails to compile.

    The strconv version needs import "strconv" in a full program, and the compiler rejects an import that nothing uses.

    Checking your fix

    Run the code in the editor above. A correct fix compiles and prints the three sentences, each naming a different language, one per line.

    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free