在Lambda函数中获取接口引用

时间:2018-08-17 18:36:52

标签: java android lambda kotlin functional-interface

考虑以下代码:

val hwnd = Handler()
hwnd.postDelayed(object : Runnable {
        override fun run()
            hwnd.postDelayed(this, 5000)
        }
}, 5000)

这样,我可以通过在this方法中使用run()(指的是Runnable)将相同的Runnable发布到处理程序。但是我怎么能只使用lambda表达式呢?

val hwnd = Handler()
hwnd.postDelayed({
    //How to get "this" here?
}, 5000)

那有可能吗?

3 个答案:

答案 0 :(得分:3)

不可能那样。您可以参考this discussion在SAM中可以访问“ this”吗?

  Lambda中的

this指包含类的实例,如果   任何。 lambda从概念上讲是一个函数,而不是一个类,因此没有   this可以引用的lambda实例。

     

lambda可以转换为SAM实例的事实   界面不会改变这一点。将this放入lambda表示不同   取决于lambda是否获得SAM转换的事情是   十分混乱。

您可以创建一个解决方法(例如,如讨论中所建议的那样):创建扩展功能:

inline fun runnable(crossinline body: Runnable.() -> Unit) = object : Runnable {
    override fun run() = body()
}

然后您可以像

那样称呼它
hwnd.postDelayed(runnable { hwnd.postDelayed(this, 5000) }, 5000)

答案 1 :(得分:3)

由于默认的lambda转换会为您提供签名为directory的lambda,这意味着基础() -> Unit被完全隐藏。

您必须处理手动对象创建,或者编写一个包装扩展函数,该函数将使用带有另一个签名的lambda:

Runnable

然后在调用方将为您提供// custom extension function for handler inline fun Handler.postDelayed(delayMilis: Long, crossinline runnable: (Runnable) -> Unit) = postDelayed(object : Runnable{ override fun run() { runnable(this) } }, delayMilis) 对象作为lambda参数(仅参数:Runnable):

it

或者,如果您想花哨的话,将扩展名参数更改为hwnd.postDelayed(5000){ // it : Runnable hwnd.postDelayed(it, 5000) } ,则可以调用:

Handler.(Runnable) -> Unit

答案 2 :(得分:0)