Start learning free

LESSON 107 OF 348 · FOR LOOPS - LOOPING OVER ARRAYS

Fixing a Buggy For Loop in Kotlin: Looping Over an Array

Practice Read the full explanation

Inside the code editor we've tried to write a for loop that greets every student in the students array.

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

Welcome, Andy
Welcome, Sally
Welcome, John

but it seems like we made some mistakes because when we run our code, it produces errors.


Assignment:

Your task is to fix our loop such that no errors will be produced and it will print the desired output.

STEP 1 OF 1
    Ctrl + Enter to check

    KOTLIN · FOR LOOPS - LOOPING OVER ARRAYS

    Buggy Code For Loops 1 in Kotlin, explained

    What the code is supposed to do

    The array students holds three names. The loop should greet each one, so the program prints:

    Welcome, Andy
    Welcome, Sally
    Welcome, John
    

    The code you start with does not compile, so nothing is printed at all:

    val students = arrayOf("Andy", "Sally", "John")
    
    for (name in students) {
    }
    println("Welcome, $student")
    

    It contains two separate mistakes. Even with only the first one fixed, the program would still fail, so you have to find both.

    Mistake 1: the print is outside the loop

    The body of a for loop is everything between its braces. In this code the braces are empty, so the loop passes over the three students and does nothing. The println line comes after the closing brace, which means it belongs to the code that runs once, after the loop has finished.

    Printing once is not what the task asks for. The greeting has to run for each student, so it must sit inside the braces:

    for (name in students) {
        println("Welcome, $student")
    }
    

    Indentation does not matter to the compiler. Indenting the println line would not move it into the loop. Only the braces decide where the body starts and ends.

    Mistake 2: the name does not match

    The loop declares its variable as name, but the string asks for $student. No variable with that name exists, so the compiler stops with an error:

    error: unresolved reference 'student'.
        println("Welcome, $student")
                           ^^^^^^^
    

    This is why the error remains after the first fix. Moving the line inside the loop puts it where name is available, but the template still names a different variable. The loop variable exists only inside the loop body, and its name is whatever the for line says.

    There is a related trap. If you leave the println outside the loop and change it to $name, you get the same kind of error, unresolved reference 'name', because the loop variable does not exist after the closing brace.

    Fixing it step by step

    1. Read the error. It points at $student and says the reference is unresolved. Something is named wrongly or is out of reach.
    2. Move the print into the body. Put the println line between the braces so it runs for every student.
    3. Make the names agree. Either rename the loop variable to student, or change the template to $name. Both work, and both print the same output. A name that says what the item is, such as student, reads better.
    4. Run it. It should print the three welcome lines, in the order of the array.

    The solution in Kotlin

    val students = arrayOf("Andy", "Sally", "John")
    
    for (student in students) {
        println("Welcome, $student")
    }
    
    /* Explanation:
    
    There are two problems with the original code:
    1. The println() statement was placed outside the brackets, therefore Kotlin would consider it as not part of the loop.
    We'll have to move it inside the brackets like this:
    
    for (name in students) {
        println("Welcome, $student")
    }
    
    2. If you run the code above, you'd still get an error.
    This is because inside the println() we use a variable named "student", which doesn't exist. The loop variable is named "name".
    There are two possible fixes to this:
    
    a. Use the loop variable "name" instead of "student" inside the println():
    for (name in students) {
        println("Welcome, $name")
    }
    
    b. Change the loop variable's name to "student" instead of "name":
    for (student in students) {
        println("Welcome, $student")
    }
    
    */
    

    The part that matters is the first six lines. The block comment is only an explanation and has no effect on the program. In Kotlin, /* ... */ comments can span many lines.

    A few Kotlin details are worth knowing:

    • The loop variable needs no declaration. The for line itself declares student, so it carries no val and no type. Its type, String, comes from the array.
    • The variable is limited to the loop. It is visible inside the braces and nowhere else.
    • Templates need a real variable. The text after $ is looked up like any other name. A name that does not exist is a compile error, not an empty string, which makes this kind of typo easy to catch.
    • An unused variable is only a warning. In the original code, name is never used. The compiler may warn about it, but it does not stop the build. The unresolved reference does.

    Common mistakes

    • Fixing only one problem. Moving the print inside the loop is not enough if the names still disagree, and the other way round.
    • Changing both names to something new. The loop variable and the template must match. Renaming one side to a third name leaves them different.
    • Using the array name in the template. $students compiles, because the variable exists, but it prints the array object instead of one name. The output is not the three greetings.
    • Misspelling the greeting. The text Welcome, includes the comma and the space. Anything else changes the output.

    Checking your fix

    Run the code in the editor above. A correct fix prints Welcome, Andy, Welcome, Sally and Welcome, John, each on its own line. If the compiler still reports an unresolved reference, compare the name in the for line with the name after the $.

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