Problem overview
The class Solution has a function welcomeUser that takes a name and prints a welcome message. mainFunction calls it twice, once with "Andy" and once with "John", so the expected output is:
Welcome, Andy!
Welcome, John!
The starting code compiles, but it prints Welcome, Andy! twice. Nothing crashes and no error appears. The program simply does the wrong thing, which makes this kind of bug easy to overlook.
class Solution {
fun welcomeUser(name: String) {
println("Welcome, Andy!")
}
fun mainFunction() {
welcomeUser("Andy")
welcomeUser("John")
}
}
What goes wrong
Look at the line inside welcomeUser. It prints the fixed text "Welcome, Andy!". The word Andy is part of the string literal, so it is the same on every call. The parameter name is declared in the header, receives "Andy" on the first call and "John" on the second, and then is never read.
Kotlin doesn't require a function to use its parameters, so it accepts the code, at most with a warning that the parameter is never used. The call welcomeUser("John") does reach the function, and the value "John" is stored in name. The body just ignores it.
A parameter is a placeholder for a value the caller chooses. It has an effect only when the body uses it. Text inside double quotes is always literal text: the characters name inside quotes would print the word "name", not the value of the variable.
The fix
Build the message from fixed pieces and the variable. The greeting has three parts: the text "Welcome, ", the value of name, and the text "!". Joining them with + gives the message:
- Keep the opening text,
"Welcome, ", including the comma and the space after it. - Add
+ name +after it, so the variable's value goes into the message. - Finish with
"!"for the exclamation mark.
With name holding "John", the pieces join into Welcome, John!.
The solution in Kotlin
class Solution {
fun welcomeUser(name: String) {
println("Welcome, " + name + "!")
}
fun mainFunction() {
welcomeUser("Andy")
welcomeUser("John")
}
}
Some details about this code:
- The
+operator joins strings. It puts nothing between the parts, so every space and punctuation mark you want must be inside one of the quoted pieces. - String templates are an alternative. Kotlin lets you write a variable inside a string with
$, soprintln("Welcome, $name!")prints the same text. The characters after$up to the next character that can't be part of a name are taken as the variable. Here the!ends the name. - The functions are members of a class.
welcomeUserandmainFunctionsit insideclass Solution, andmainFunctioncallswelcomeUserwithout any prefix because both belong to the same object. - The function returns nothing. It prints the message, so its return type is
Unit, which you don't need to write.
Common mistakes
- Changing the calls instead of the function. The calls are already correct. The fix belongs in the one line of
welcomeUser. - Putting the variable in quotes.
"Welcome, name!"prints the wordname, not the value. - Losing the spaces.
"Welcome," + namewithout the space after the comma printsWelcome,John!. - Forgetting the exclamation mark or typing it with a different character. The output has to match exactly.
- Adding another
println. Each call must print one line. Two print statements in the function would print two lines for every call.
A habit worth building
When a function gives the same result for different arguments, check the body for each parameter: is it read anywhere? A parameter that is never used is a strong hint that something was hard-coded by mistake. Compare the two results you get against the two you expect, and see exactly which part of the output stayed fixed.