Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kotlin - Pass method reference to function

Let's say I have the following Java class:

public class A {
   public Result method1(Object o) {...}
   public Result method2(Object o) {...}
   ...
   public Result methodN(Object o) {...}
}

Then, in my Kotlin code:

fun myFunction(...) {
    val a: A = ...
    val parameter = ...
    val result = a.method1(parameter) // what if i want methodX?
    do more things with result
}

and I want to be able to choose which methodX will be called inside myFunction. in Java, I would pass A::method7 as an argument and call it. in Kotlin it doesn't compile. How should I solve it in Kotlin?

like image 948
piotrek Avatar asked Feb 09 '18 15:02

piotrek


People also ask

Can you pass by reference in Kotlin?

Since no assignment is possible for function parameters, the main advantage of passing by reference in C++ does not exist in Kotlin. If the object (passed to the function) has a method which changes its internal state, it will affect the original object. No such method exists for Int, String, etc.

How do you pass a function as an argument in Kotlin?

myfunc: (String) -> Unit represents that it accept function as a parameter which returns Unit. From main function, higher function is invoked by passing the string and function as arguments.

How do you pass a list to a function in Kotlin?

Create a new List using the Kotlin standard library function listOf() , and pass in the elements of the list as arguments separated by commas. listOf(1, 2, 3, 4, 5, 6) returns a read-only list of integers from 1 through 6.

How do you pass Varargs to another function Kotlin?

In Kotlin, You can pass a variable number of arguments to a function by declaring the function with a vararg parameter. a vararg parameter of type T is internally represented as an array of type T ( Array<T> ) inside the function body.


2 Answers

You can also pass the method reference in Kotlin (without needing the heavy hammer that is reflection):

fun myFunction(method: A.(Any) -> Result) {
    val a: A = ...
    val parameter = ...
    val result = a.method(parameter)
    do more things with result
}

myFunction(A::method1)
myFunction {/* do something in the context of A */}

This declares method as part of A, meaning you can call it with normal object.method() notation. It Just Works™ with the method reference syntax.

There's also another form that works with the same call syntax, but makes A more explicit:

fun myFunction(method: (A, Any) -> Result) { ... }

myFunction(A::method1)
myFunction {a, param -> /* do something with the object and parameter */}
like image 189
chris Avatar answered Sep 22 '22 07:09

chris


You can actually do this exactly like you wanted to:

fun myFunction(kFunction: KFunction2<A, @ParameterName(name = "any") Any, Result>) {
    val parameter = "string"
    val result: Result = kFunction(A(), parameter)
    //...
}

myFunction(A::method1)
myFunction(A::method2)
like image 40
s1m0nw1 Avatar answered Sep 22 '22 07:09

s1m0nw1