How can I pass property getter to a function that accepts function type?
Here is an example of what I want achieve:
class Test {
val test: String
get() = "lol"
fun testFun(func: ()->String) {
// invoke it here
}
fun callTest() {
testFun(test::get)
// error: Type mismatch: inferred type is
// KFunction1<@ParameterName Int, Char> but () -> String was expected
}
}
Is there a way?
You can reference the getter by writing ::test
(or this::test
).
When you write test::get
, you are actually referencing the get
method on String
. That method takes an index and returns the character at that index.
If the property was a var
and you want a reference to its setter, you can write ::test::set
.
For more info on property references, see here: https://kotlinlang.org/docs/reference/reflection.html#bound-function-and-property-references-since-11
As already mentioned, you can use this::test
to refer to the getter. Alternatively, if you have kotlin-reflect
, you can do this::test.getter
.
When you pass the field as a function, it assumes you mean the getter. As a result, if you want the setter, you have two options:
this::test::set
or
this::test.setter
The latter, just like this::test.getter
requires kotlin-reflect
, or the program will crash (tested locally with Kotlin 1.2.50)
You can, however, get the getter in another way. But I recommend you just stick with this::test
because it's shorter.
You can do:
this::something::get
With just something::get
it refers to the method inside the String class, which returns a char at an index. For reference, the method declaration:
public override fun get(index: Int): Char
If you don't mind, just use { test }
(e.g. testFun { test }
). This will exactly translate to your () -> String
. The next best alternative is probably ::test
(or this::test
) as was already mentioned.
The second has probably only minor (negligible?) impact on performance. I did not test it myself, nor did I found any source which tells something regarding it. The reason why I say this, is how the byte code underneath looks like. Just due to this question I asked myself about the difference of the two: Is the property reference (::test) equivalent to a function accessing the property ({ test }) when passed as argument e.g. `() -> String`?
It seems that you are doing something wrong on logical level.
If you are overriding get
method of a variable, then you can access it's value through this get method. Thus, why bother with test::get
(which is totally different method, by the way, all you are doing is trying to access char
from string
), when you can just access variable by it's name?