The quiz
The quiz shows a function with a print placed after a return, and asks what the program prints when mainFunction runs:
func greetAndReturn() -> String {
return "How are you doing?"
print("Hey bro!")
}
func mainFunction() {
let question = greetAndReturn()
print(question)
}
The options are four possible outputs: A has Hey bro! and then How are you doing?, B has only How are you doing?, C has How are you doing? and then Hey bro!, and D has only Hey bro!. The answer is submitted as a constant: let answer = "B" for option B.
How to reason about it
Follow the program the way Swift does, one statement at a time.
mainFunctioncallsgreetAndReturn()and waits for its result.- Inside
greetAndReturn, the first statement isreturn "How are you doing?". Areturnends the function on the spot and sends the value back to the caller. - The line
print("Hey bro!")comes after thereturn, so it never runs. - Back in
mainFunction,questionreceives"How are you doing?", andprint(question)prints it.
The program prints one line:
How are you doing?
That is option B. Options A and C need Hey bro! to be printed, and option D doesn't print the returned text at all.
Why this is easy to get wrong
The two statements sit in the function body, and a quick reader assumes both run. But return is not just "give back a value": it also leaves the function. Everything below it in that path is dead code.
Swift even points this out. If you compile the function, the compiler gives a warning, not an error:
warning: code after 'return' will never be executed
The program still builds and runs, and the unreachable print is skipped. The same is true for any statements after a return in the same block. The order of the lines matters.
Where the print would run
If the greeting had to appear, it would need to come first:
func greetAndReturn() -> String {
print("Hey bro!")
return "How are you doing?"
}
Now the output is Hey bro! and then How are you doing?, which is option A.
Returning early on purpose
Skipping the code after a return is often what you want. A function can return from inside an if, and the lines after the if run only when that branch isn't taken:
func label(_ n: Int) -> String {
if n < 0 {
return "negative"
}
print("checked sign")
return "not negative"
}
print(label(-5))
print(label(3))
This prints:
negative
checked sign
not negative
For -5 the function leaves inside the if, so checked sign is not printed. For 3 the if is skipped and the function continues to the end. In the quiz there is no condition, so the return is always reached first.
The solution in Swift
let answer = "B"
/* Explanation:
Remember, whenever Swift hits a "return" statement inside a function, the value is being returned from the function
and the function call ends immediately after that. Even if there are more lines of code coming after the "return", they will not be executed.
In our case, when we call greetAndReturn(), the string "How are you doing?" is being returned and the function call ends.
Thus, the print("Hey bro!") will never get executed.
However, variable greeting will be assigned the returned string "How are you doing?", which will be printed to the console.
*/
Two Swift details apply. let declares a constant, which suits an answer that never changes, and the letter is a string, so it goes in double quotes. The block between /* and */ is a comment that Swift ignores.
A habit for quizzes like this
Write down, line by line, what the program does and what it prints, as if you were the computer. Mark the line where the function ends. For this quiz that is the return, so only the lines before it, and the caller's lines after the call, can produce output. Trace first and look at the options afterwards, so a tempting wrong option doesn't steer you.
Common mistakes
- Assuming every line in a function runs. A
returnskips whatever follows it. - Thinking
returnprints. Onlyprint(question)inmainFunctionproduces output. - Typing the answer without quotes.
let answer = Blooks for a variable namedB;"B"is the string.
