如何将属性获取器作为函数类型传递给另一个函数

时间:2018-08-14 11:54:00

标签: properties kotlin getter

如何将属性获取器传递给接受函数类型的函数?

以下是我想要实现的示例:

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
    }
}

有办法吗?

4 个答案:

答案 0 :(得分:2)

您可以通过编写::test(或this::test)来引用吸气剂。

在编写test::get时,实际上是在get上引用String方法。该方法获取索引并返回该索引处的字符。

如果该属性是var,并且您想要引用其设置方法,则可以编写::test::set

有关属性引用的更多信息,请参见此处:https://kotlinlang.org/docs/reference/reflection.html#bound-function-and-property-references-since-11

答案 1 :(得分:1)

如上所述,您可以使用this::test来引用getter。或者,如果您有kotlin-reflect,则可以进行this::test.getter

当您将该字段作为函数传递时,它假定您是指吸气剂。结果,如果您想要二传手,则有两个选择:

this::test::set

this::test.setter

后者就像this::test.getter需要kotlin-reflect,否则程序将崩溃(使用Kotlin 1.2.50在本地测试)

但是,您可以通过其他方式获得吸气剂。但我建议您坚持使用this::test,因为它更短。

您可以这样做:

this::something::get

仅使用something::get即可引用String类中的方法,该方法在索引处返回一个char。作为参考,方法声明:

public override fun get(index: Int): Char

答案 2 :(得分:1)

如果您不介意,只需使用{ test }(例如testFun { test })即可。这将完全转换为您的() -> String。如前所述,下一个最佳选择可能是::test(或this::test)。

第二个对性能的影响可能很小(可忽略不计?)。我自己没有测试过,也没有找到任何有关它的信息。我这么说的原因是下面的字节码看起来像。正是由于这个问题,我才问自己关于两者的区别:Is the property reference (::test) equivalent to a function accessing the property ({ test }) when passed as argument e.g. `() -> String`?

答案 3 :(得分:0)

看来您在逻辑上做错了事。

如果您要覆盖变量的models.py方法,则可以通过此get方法访问其值。因此,为什么要打扰views.py(顺便说一句,这是完全不同的方法,您正在做的就是尝试从get访问test::get),而您只能通过它来访问变量名字?