If you already have a member function that you'd like to assign to a function type, you could wrap it inside a lambda:
var numFunc: (Int, Int) -> Int = { a, b -> multiplier(a, b) }
fun multiplier(a: Int, b: Int): Int {
return a * b
}
You can also initialize the function type directly with a member reference, the same as you can in Java 8:
var numFunc: (Int, Int) -> Int = this::multiplier
fun multiplier(a: Int, b: Int): Int {
return a * b
}
Member references are expressed with the :: operator. On the left-hand side of the operator is the object that holds the function. We use this since we are referring to the same object that holds the numFunc function type property. On the right-hand side is the function name.
When the function is declared in the same class or the same file as the function type variable, you can omit the this from the left-hand side of the :: operator. We can also write it like this:
var numFunc: (Int, Int) -> Int = ::multiplier
The member function has to have the same signature as the function type that is being initialized; otherwise, you'd get a compiler error:
//compiler error
var numFunc: (Int, Int) -> Int = this::printNums
fun printNums(a: Int, b: Int) {
println("$a and $b")
}
And if you want to use a function from some other object to initialize a function type variable, you just have to set the name of the object variable on the left-hand side of the :: operator, as the following example shows:
val str = "Kotlin"
val getChar: (Int) -> Char = str::get
Member references can also be used to get a reference to a class constructor. Constructors are also functions, so we can store a reference to it and invoke it later. The syntax for targeting a class constructor looks like this; it's just the class name after the :: operator:
class Person(val name: String)
val personConstructor = ::Person
Now, we can invoke a person constructor function type and we'll get an instance of the Person type:
val person: Person = personConstructor("John")