Functions
You can declare your own functions in Kotlin using the fun
keyword.
In Kotlin:
Function parameters are written within parentheses
()
.Each parameter must have a type, and multiple parameters must be separated by commas
,
.The return type is written after the function's parentheses
()
, separated by a colon:
.The body of a function is written within curly braces
{}
.The
return
keyword is used to exit or return something from a function.
In the following example:
x
andy
are function parameters.x
andy
have typeInt
.The function's return type is
Int
.The function returns a sum of
x
andy
when called.
Named arguments
For concise code, when calling your function, you don't have to include parameter names. However, including parameter names does make your code easier to read. This is called using named arguments. If you do include parameter names, then you can write the parameters in any order.
Default parameter values
You can define default values for your function parameters. Any parameter with a default value can be omitted when calling your function. To declare a default value, use the assignment operator =
after the type:
Functions without return
If your function doesn't return a useful value then its return type is Unit
. Unit
is a type with only one value – Unit
. You don't have to declare that Unit
is returned explicitly in your function body. This means that you don't have to use the return
keyword or declare a return type:
Single-expression functions
To make your code more concise, you can use single-expression functions. For example, the sum()
function can be shortened:
You can remove the curly braces {}
and declare the function body using the assignment operator =
. When you use the assignment operator =
, Kotlin uses type inference, so you can also omit the return type. The sum()
function then becomes one line:
However, if you want your code to be quickly understood by other developers, it's a good idea to explicitly define the return type even when using the assignment operator =
.
Early returns in functions
To stop the code in your function from being processed further than a certain point, use the return
keyword. This example uses if
to return from a function early if the conditional expression is found to be true:
Functions practice
Exercise 1
Write a function called circleArea
that takes the radius of a circle in integer format as a parameter and outputs the area of that circle.
Exercise 2
Rewrite the circleArea
function from the previous exercise as a single-expression function.
Exercise 3
You have a function that translates a time interval given in hours, minutes, and seconds into seconds. In most cases, you need to pass only one or two function parameters while the rest are equal to 0. Improve the function and the code that calls it by using default parameter values and named arguments so that the code is easier to read.
Lambda expressions
Kotlin allows you to write even more concise code for functions by using lambda expressions.
For example, the following uppercaseString()
function:
Can also be written as a lambda expression:
Lambda expressions can be hard to understand at first glance so let's break it down. Lambda expressions are written within curly braces {}
.
Within the lambda expression, you write:
The parameters followed by an
->
.The function body after the
->
.
In the previous example:
text
is a function parameter.text
has typeString
.The function returns the result of the
.uppercase()
function called ontext
.The entire lambda expression is assigned to the
upperCaseString
variable with the assignment operator=
.The lambda expression is called by using the variable
upperCaseString
like a function and the string"hello"
as a parameter.The
println()
function prints the result.
Lambda expressions can be used in a number of ways. You can:
Pass to another function
A great example of when it is useful to pass a lambda expression to a function, is using the .filter()
function on collections:
The .filter()
function accepts a lambda expression as a predicate:
{ x -> x > 0 }
takes each element of the list and returns only those that are positive.{ x -> x < 0 }
takes each element of the list and returns only those that are negative.
This example demonstrates two ways of passing a lambda expression to a function:
For positive numbers, the example adds the lambda expression directly in the
.filter()
function.For negative numbers, the example assigns the lambda expression to the
isNegative
variable. Then theisNegative
variable is used as a function parameter in the.filter()
function. In this case, you have to specify the type of function parameters (x
) in the lambda expression.
Another good example, is using the .map()
function to transform items in a collection:
The .map()
function accepts a lambda expression as a transform function:
{ x -> x * 2 }
takes each element of the list and returns that element multiplied by 2.{ x -> x * 3 }
takes each element of the list and returns that element multiplied by 3.
Function types
Before you can return a lambda expression from a function, you first need to understand function types.
You have already learned about basic types but functions themselves also have a type. Kotlin's type inference can infer a function's type from the parameter type. But there may be times when you need to explicitly specify the function type. The compiler needs the function type so that it knows what is and isn't allowed for that function.
The syntax for a function type has:
Each parameter's type written within parentheses
()
and separated by commas,
.The return type written after
->
.
For example: (String) -> String
or (Int, Int) -> Int
.
This is what a lambda expression looks like if a function type for upperCaseString()
is defined:
If your lambda expression has no parameters then the parentheses ()
are left empty. For example: () -> Unit
Return from a function
Lambda expressions can be returned from a function. So that the compiler understands what type the lambda expression returned is, you must declare a function type.
In the following example, the toSeconds()
function has function type (Int) -> Int
because it always returns a lambda expression that takes a parameter of type Int
and returns an Int
value.
This example uses a when
expression to determine which lambda expression is returned when toSeconds()
is called:
Invoke separately
Lambda expressions can be invoked on their own by adding parentheses ()
after the curly braces {}
and including any parameters within the parentheses:
Trailing lambdas
As you have already seen, if a lambda expression is the only function parameter, you can drop the function parentheses ()
. If a lambda expression is passed as the last parameter of a function, then the expression can be written outside the function parentheses ()
. In both cases, this syntax is called a trailing lambda.
For example, the .fold()
function accepts an initial value and an operation:
For more information on lambda expressions, see Lambda expressions and anonymous functions.
The next step in our tour is to learn about classes in Kotlin.
Lambda expressions practice
Exercise 1
You have a list of actions supported by a web service, a common prefix for all requests, and an ID of a particular resource. To request an action title
over the resource with ID: 5, you need to create the following URL: https://example.com/book-info/5/title
. Use a lambda expression to create a list of URLs from the list of actions.
Exercise 2
Write a function that takes an Int
value and an action (a function with type () -> Unit
) which then repeats the action the given number of times. Then use this function to print “Hello” 5 times.