Kotlin functions are declared using the
Functions are called using the standard approach:
Calling member functions uses dot notation:
Function parameters are defined using Pascal notation - name: type. Parameters are separated using commas, and each parameter must be explicitly typed:
You can use a trailing comma when you declare function parameters:
Function parameters can have default values, which are used when you skip the corresponding argument. This reduces the number of overloads:
A default value is defined using
= after the type.
Overriding methods always use the same default parameter values as the base method. When overriding a method that has default parameter values, the default parameter values must be omitted from the signature:
If a default parameter precedes a parameter with no default value, the default value can only be used by calling the function with named arguments:
When calling a function, you can name one or more of its arguments. This can be helpful when a function has many arguments and it's difficult to associate a value with an argument, especially if it's a boolean or
When you use named arguments in a function call, you can freely change the order they are listed in, and if you want to use their default values, you can just leave these arguments out altogether.
Consider the following function,
reformat(), which has 4 arguments with default values.
When calling this function, you don’t have to name all its arguments:
You can skip all the ones with default values:
You are also able to skip specific arguments with default values, rather than omitting them all. However, after the first skipped argument, you must name all subsequent arguments:
You can pass a variable number of arguments (
vararg) with names using the
If a function does not return a useful value, its return type is
Unit is a type with only one value -
Unit. This value does not have to be returned explicitly:
Unit return type declaration is also optional. The above code is equivalent to:
When a function returns a single expression, the curly braces can be omitted and the body is specified after a
Explicitly declaring the return type is optional when this can be inferred by the compiler:
Explicit return types
Functions with block body must always specify return types explicitly, unless it's intended for them to return
Unit, in which case specifying the return type is optional.
Kotlin does not infer return types for functions with block bodies because such functions may have complex control flow in the body, and the return type will be non-obvious to the reader (and sometimes even for the compiler).
Variable number of arguments (varargs)
You can mark a parameter of a function (usually the last one) with the
In this case, you can pass a variable number of arguments to the function:
Inside a function, a
vararg-parameter of type
T is visible as an array of
T, as in the example above, where the
ts variable has type
Only one parameter can be marked as
vararg. If a
vararg parameter is not the last one in the list, values for the subsequent parameters can be passed using named argument syntax, or, if the parameter has a function type, by passing a lambda outside the parentheses.
When you call a
vararg-function, you can pass arguments individually, for example
asList(1, 2, 3). If you already have an array and want to pass its contents to the function, use the spread operator (prefix the array with
If you want to pass a primitive type array into
vararg, you need to convert it to a regular (typed) array using the
Functions marked with the
infix keyword can also be called using the infix notation (omitting the dot and the parentheses for the call). Infix functions must meet the following requirements:
They must be member functions or extension functions.
They must have a single parameter.
Note that infix functions always require both the receiver and the parameter to be specified. When you're calling a method on the current receiver using the infix notation, use
this explicitly. This is required to ensure unambiguous parsing.
Kotlin functions can be declared at the top level in a file, meaning you do not need to create a class to hold a function, which you are required to do in languages such as Java, C#, and Scala. In addition to top level functions, Kotlin functions can also be declared locally as member functions and extension functions.
Kotlin supports local functions, which are functions inside other functions:
A local function can access local variables of outer functions (the closure). In the case above,
visited can be a local variable:
A member function is a function that is defined inside a class or object:
Member functions are called with dot notation:
Functions can have generic parameters, which are specified using angle brackets before the function name:
For more information on generic functions, see Generics.
Tail recursive functions
Kotlin supports a style of functional programming known as tail recursion. For some algorithms that would normally use loops, you can use a recursive function instead without the risk of stack overflow. When a function is marked with the
tailrec modifier and meets the required formal conditions, the compiler optimizes out the recursion, leaving behind a fast and efficient loop based version instead:
This code calculates the
fixpoint of cosine, which is a mathematical constant. It simply calls
Math.cos repeatedly starting at
1.0 until the result no longer changes, yielding a result of
0.7390851332151611 for the specified
eps precision. The resulting code is equivalent to this more traditional style:
To be eligible for the
tailrec modifier, a function must call itself as the last operation it performs. You cannot use tail recursion when there is more code after the recursive call, within
finally blocks, or on open functions. Currently, tail recursion is supported by Kotlin for the JVM and Kotlin/Native.