Why functions take input
The functions so far did the same thing every time. A function like sayHello() can print only one fixed message. Usually you want the result to depend on the situation: a greeting for humans in one call and for cats in another. Parameters make that possible.
Parameters and arguments
A parameter is a placeholder for a value, declared in the parentheses of the function definition. In Kotlin, a parameter is written as its name, a colon and its type:
fun sayHello(audience: String) {
println("Hello $audience")
}
An argument is the actual value passed in a call. Inside the function, the parameter behaves like a variable holding that value:
sayHello("humans")
Hello humans
In short, the parameter is the name in the definition, and the argument is the value in the call. Each call can pass a different argument, so one definition serves any audience.
String templates
The text "Hello $audience" is a string template. A dollar sign followed by a name is replaced by that variable's value. To insert a longer expression, use braces: "${name.length}" inserts the length of name. Without braces, only the name right after the $ is substituted, so with val name = "Andy", the text "$name.length" gives Andy.length and not 4.
Several parameters
A function can have as many parameters as it needs, separated by commas:
fun sayHello(name: String, age: Int) {
println("$name, aged $age")
}
fun main() {
sayHello("John", 30)
sayHello("Mary", 26)
}
John, aged 30
Mary, aged 26
Arguments are matched to parameters by position: the first argument goes to the first parameter, the second to the second. Swapping them is an error here, since 26 is not a String. Kotlin also lets you name the arguments in a call, which makes the order free: sayHello(age = 26, name = "Mary") prints the same line as before.
Variables as arguments
An argument can be any expression, including a variable. The function receives the variable's value. The variable in the caller and the parameter in the function are different names that happen to hold the same value, and they don't have to match: a caller's val name = "Andy" can be passed to a parameter called anything.
What the compiler checks
Parameter types are checked when the code is compiled. For a function welcomeUser(name: String):
- calling
welcomeUser()with no argument gives the errorno value passed for parameter 'name'.; - calling
welcomeUser(5)givesargument type mismatch: actual type is 'Int', but 'String' was expected.; - calling
welcomeUser("a", "b")reports too many arguments; - assigning to the parameter inside the function, as in
name = "x", gives'val' cannot be reassigned., because Kotlin parameters are read-only.
The lesson's exercise, step by step
The starter code is a class named Solution with an empty mainFunction. All the code goes inside the class.
- Define
welcomeUserwith oneStringparameter calledname, abovemainFunction. - Print a greeting with a string template. The body is
println("Welcome, $name!"), so for"Andy"it printsWelcome, Andy!. The exclamation mark right after$namedoesn't belong to the name, because a name can't contain it. - Call
welcomeUser("Andy")insidemainFunction. The string argument becomes the value ofnamefor that call. - Create
val name = "John"inmainFunction. It is aval, since the value is never reassigned. - Call
welcomeUser(name). The variable's value,"John", is the argument.
class Solution {
fun welcomeUser(name: String) {
println("Welcome, $name!")
}
fun mainFunction() {
welcomeUser("Andy")
val name = "John"
welcomeUser(name)
}
}
Calling mainFunction() on a Solution object prints:
Welcome, Andy!
Welcome, John!
Here the functions are written inside a class, which makes them member functions. They can call each other by name, as mainFunction calls welcomeUser. Outside the class, you would call them on an object, as in Solution().mainFunction().
Common mistakes
- Omitting the type.
fun welcomeUser(name)is not valid, because every Kotlin parameter needs a type. - Writing the type first.
String nameis the order of other languages. Kotlin usesname: String. - Forgetting the dollar sign.
"Welcome, name!"prints the wordnameand not the value. - Passing arguments in the wrong order. With several parameters of the same type, a swap compiles and prints wrong output.
Key takeaways
- Parameters are declared in the definition as
name: Type. Arguments are the values given in the call. - Arguments are matched by position, or by name when you write the name in the call.
- Parameters are read-only inside the function.
$nameputs a variable into a string, and${...}puts in an expression.