Kotlin functions are declared using the fun double(x: Int): Int { return 2 * x } Functions are called using the standard approach: val result = double(2) Calling member functions uses dot notation: Stream().read() // create instance of class Stream and call read() Function parameters are defined using Pascal notation - name: type. Parameters are separated using commas, and each parameter must be explicitly typed: fun powerOf(number: Int, exponent: Int): Int { /*...*/ } You can use a trailing comma
when you declare function parameters: fun powerOf( number: Int, exponent: Int, // trailing comma ) { /*...*/ } Function parameters can have default values, which are used when you skip the corresponding argument. This reduces the number of overloads: fun read( b: ByteArray, off: Int = 0, len: Int = b.size, ) { /*...*/ } A default value is defined
using 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: open class A { open fun foo(i: Int = 10) { /*...*/ } } class B : A() { override fun foo(i: Int) { /*...*/ } // No default value is allowed. } 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: fun foo( bar: Int = 0, baz: Int, ) { /*...*/ } foo(baz = 1) // The default value bar = 0 is used If the last argument after default parameters is a lambda, you can pass it either as a named argument or outside the parentheses: fun foo( bar: Int = 0, baz: Int = 1, qux: () -> Unit, ) { /*...*/ } foo(1) { println("hello") } // Uses the default value baz = 1 foo(qux = { println("hello") }) // Uses both default values bar = 0 and baz = 1 foo { println("hello") } // Uses both default values bar = 0 and baz = 1 Named argumentsWhen 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, fun reformat( str: String, normalizeCase: Boolean = true, upperCaseFirstLetter: Boolean = true, divideByCamelHumps: Boolean = false, wordSeparator: Char = ' ', ) { /*...*/ } When calling this function, you don't have to name all its arguments: reformat( "String!", false, upperCaseFirstLetter = false, divideByCamelHumps = true, '_' ) You can skip all the ones with default values: reformat("This is a long String!") 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: reformat("This is a short String!", upperCaseFirstLetter = false, wordSeparator = '_') You can pass a
variable number of arguments ( fun foo(vararg strings: String) { /*...*/ } foo(strings = *arrayOf("a", "b", "c")) Unit-returning functionsIf a function does not return a useful value, its return type is
fun printHello(name: String?): Unit { if (name != null) println("Hello $name") else println("Hi there!") // `return Unit` or `return` is optional } The fun printHello(name: String?) { ... } Single-expression functionsWhen a function returns a single expression, the curly braces can be omitted and the body is specified after a fun double(x: Int): Int = x * 2 Explicitly declaring the return type is optional when this can be inferred by the compiler: fun double(x: Int) = x * 2 Explicit return typesFunctions with block body must always specify return types explicitly, unless it's intended for them to return 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 fun <T> asList(vararg ts: T): List<T> { val result = ArrayList<T>() for (t in ts) // ts is an Array result.add(t) return result } In this case, you can pass a variable number of arguments to the function: val list = asList(1, 2, 3) Inside a function, a Only one parameter can be marked as When you call a val a = arrayOf(1, 2, 3) val list = asList(-1, 0, *a, 4) If you want to pass a primitive type array into val a = intArrayOf(1, 2, 3) // IntArray is a primitive type array val list = asList(-1, 0, *a.toTypedArray(), 4) Infix notationFunctions marked with the
infix fun Int.shl(x: Int): Int { ... } // calling the function using the infix notation 1 shl 2 // is the same as 1.shl(2) 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 class MyStringCollection { infix fun add(s: String) { /*...*/ } fun build() { this add "abc" // Correct add("abc") // Correct //add "abc" // Incorrect: the receiver must be specified } } Function scopeKotlin 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. Local functionsKotlin supports local functions, which are functions inside other functions: fun dfs(graph: Graph) { fun dfs(current: Vertex, visited: MutableSet<Vertex>) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v, visited) } dfs(graph.vertices[0], HashSet()) } A local function can access local variables of outer functions (the closure). In the case above, fun dfs(graph: Graph) { val visited = HashSet<Vertex>() fun dfs(current: Vertex) { if (!visited.add(current)) return for (v in current.neighbors) dfs(v) } dfs(graph.vertices[0]) } Member functionsA member function is a function that is defined inside a class or object: class Sample { fun foo() { print("Foo") } } Member functions are called with dot notation: Sample().foo() // creates instance of class Sample and calls foo For more information on classes and overriding members see Classes and Inheritance. Generic functionsFunctions can have generic parameters, which are specified using angle brackets before the function name: fun <T> singletonList(item: T): List<T> { /*...*/ } For more information on generic functions, see Generics. Tail recursive functionsKotlin 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 val eps = 1E-10 // "good enough", could be 10^-15 tailrec fun findFixPoint(x: Double = 1.0): Double = if (Math.abs(x - Math.cos(x)) < eps) x else findFixPoint(Math.cos(x)) This code calculates the val eps = 1E-10 // "good enough", could be 10^-15 private fun findFixPoint(): Double { var x = 1.0 while (true) { val y = Math.cos(x) if (Math.abs(x - y) < eps) return x x = Math.cos(x) } } To be eligible for the See also:
Last modified: 06 September 2022 When a member function is defined outside of the class declaration the function name?If a member function's definition is outside the class declaration, it is treated as an inline function only if it is explicitly declared as inline . In addition, the function name in the definition must be qualified with its class name using the scope-resolution operator ( :: ).
When we define a member function outside the class?Member functions and static members can be defined outside their class declaration if they have already been declared, but not defined, in the class member list. Nonstatic data members are defined when an object of their class is created. The declaration of a static data member is not a definition.
How is a member function of a class defined or declared?Member functions are operators and functions that are declared as members of a class. Member functions do not include operators and functions declared with the friend specifier. These are called friends of a class. You can declare a member function as static ; this is called a static member function.
How is inline member function defined outside the body of class?If you define a member function outside of its class definition, it must appear in a namespace scope enclosing the class definition. You must also qualify the member function name using the scope resolution ( :: ) operator.
|