What the code is supposed to do
The program should greet every student in the students array, printing one line per student:
Welcome, Andy
Welcome, Sally
Welcome, John
The code you start with does not compile, so nothing is printed:
let students = ["Andy", "Sally", "John"]
for name in students {
}
print("Welcome, \(student)")
The compiler reports cannot find 'student' in scope.
What goes wrong
There are two separate mistakes.
1. The print is outside the loop
The body of a loop is everything between its braces. Here the braces are empty, and the print comes after the closing brace. Even if it compiled, it would run once, after the loop had finished, instead of once per student.
2. The name does not match
The loop calls its variable name, but the string uses student. No variable called student exists anywhere, so the compiler cannot resolve it. A loop variable is also visible only inside the braces. Fixing mistake 1 alone gives the same error:
for name in students {
print("Welcome, \(student)")
}
error: cannot find 'student' in scope
Fixing it step by step
- Move the print inside the braces, so it runs once per element.
- Make the names agree. Either use
\(name)in the string, or rename the loop variable tostudent. Renaming reads better, becausestudentsays what each element is.
The reference solution renames the variable and keeps the print as written:
The fixed code in Swift
let students = ["Andy", "Sally", "John"]
for student in students {
print("Welcome, \(student)")
}
/* Explanation:
There are two problems with the original code:
1. The print() statement was placed outside the brackets, therefore Swift would consider it as not part of the loop.
We'll have to move it inside the brackets like this:
for name in students {
print("Welcome, \(student)")
}
2. If you run the code above, you'd still get an error.
This is because inside the print() 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 print():
for name in students {
print("Welcome, \(name)")
}
b. Change the loop variable's name to "student" instead of "name":
for student in students {
print("Welcome, \(student)")
}
*/
Running the loop prints the three greetings above, in array order. A few Swift details apply:
- Interpolation.
\(student)inside a string inserts the value of the variable. The name inside the parentheses must exist at that point. - Comments. The text between
/*and*/is a block comment. Swift ignores it, which is why the code in it, including the broken versions, does not affect the program. - No parentheses around the header. Swift writes
for student in students {without parentheses, but the braces are required, even for a single statement. - Unused loop variable. In the starting code,
nameis never used, which Swift reports as a warning. When you don't need the variable, writefor _ in students.
Checking your fix
Run the fixed program and compare the output with the three lines at the top. If the compiler still reports an error, read the name it complains about and look for that exact spelling. If it prints only once, or prints an unexpected result, check which lines sit between the braces.
It also helps to add a fourth name, such as "Maria", to the array. A correct loop greets her without any other change, which a copy of the print line per student would not.
Common mistakes
- Fixing only one of the two bugs. The code compiles only when the print is inside the loop and the names agree.
- Printing the whole array.
print(students)prints the array in brackets on one line, not one greeting per student. - Changing the greeting text. The output must be exactly
Welcome,followed by the name, with the comma and the space.
