Kotlin functions are defined using fun
keyword, followed by the name of the function, a pair of parentheses, optional parameters, the return type of function and then the body of the function, which is pair of curly braces. It's pretty much like a Java function, except that in Java, we have no fun
(pun intended) and the type of the function is written to the left of the function (in Java), while in Kotlin, the return type of the function is to the right of function name.
When a function declares a return type, the type and the function's name must be separated by a colon. Like this function that takes in a Float argument and returns a Float value
fun inchesToCm(inches:Float) : Float {
return inches * 2.54
}
fun main(args:Array<String) {
println(inchesToCm(10))
}
If a function has a single statement in it's body (like the previous code sample), you can write it as an expression. Like this
fun inchesToCm(inches:Float) = inches * 2.54
In a function expression, you don't have to write the return type because Kotlin can infer it from the RHS (right hand side of the assignment operator).
When a function (that isn't written as an expression) doesn't specify it's return type, the compiler will assume that it returns the Unit type. Think of Unit as the equivalent of Java's void, like this
fun talk() { // (1)
println("Hello") // (2)
}
(1) Our function doesn't have a declared return type. Hence, it's automatically Unit
(2) The body of a function whose return type is Unit cannot have any return statement in it; just like void methods in Java
Functions can be written in 3 places; as a top-level (which you've seen already) inside classes (which you've also seen) and inside another function.
fun foo() { // (1)
fun baz() : String{ // (2)
return "Bar"
}
println("Foo ${baz()}") // (3)
}
fun main(args:Array<String>) {
foo()
baz() // (4)
println("${Person(lastname="Doe", firstname = "John").fullname()}")
}
class Person(val firstname:String, val lastname:String) {
fun fullname() = "$firstname $lastname" // (5)
(1) foo()
is a top level function. It isn't nested in a class or another function
(2) bazz()
is nested inside function foo()
. Which means, baz is scoped with foo; which means, it can only be called within the body of foo()
(3) This call is ok, baz()
is callable within foo()
(4) Not OK. This call will fail, baz()
is not callable from main()
, you can only call baz()
from within foo()
(5) Like Java, you can put functions inside a class
Default function arguments
You can assign default values to function parameters, like this
fun connectToDb(hostname: String = "localhost",
username: String = "mysql",
password:String = "secret") {
}
And because there are default parameters, you can call this function without passing any arguments. Like this
connectToDb()
Or you can pass only two arguments, like this
connectToDb("mycomputer", "ted")
"mycomputer" is the hostname, "ted" is the username. The two arguments that we passed corresponds to the first two parameters that were defined in the function.
Named params
In addition to default function arguments, we can also call the function by naming the arguments at the callsite.
fun main(args:Array<String>) {
connectToDb(hostname="neptune",
username="saturn")
}
In the example above, we only passed two arguments, but since our function has default parameters, that's okay.
Some related content to this are;
Top comments (0)