问题
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?
回答1:
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
回答2:
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
回答3:
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`?
回答4:
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?
来源:https://stackoverflow.com/questions/51840809/how-can-i-pass-property-getter-as-a-function-type-to-another-function