为了账号安全,请及时绑定邮箱和手机立即绑定

在 lambda 函数中获取接口引用

在 lambda 函数中获取接口引用

神不在的星期二 2021-07-20 17:08:30
考虑以下代码:val hwnd = Handler()hwnd.postDelayed(object : Runnable {        override fun run()            hwnd.postDelayed(this, 5000)        }}, 5000)这样,我可以通过this在run()方法中使用(指的是 Runnable)将相同的 Runnable 发布到 Handler 。但是我怎么能只使用一个 lambda 表达式来做同样的事情呢?val hwnd = Handler()hwnd.postDelayed({    //How to get "this" here?}, 5000)这甚至可能吗?
查看完整描述

2 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

由于默认的 lambda 转换为您提供了签名为 的 lambda () -> Unit,这意味着底层Runnable是完全隐藏的。


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


// custom extension function for handler

inline fun Handler.postDelayed(delayMilis: Long, crossinline runnable: (Runnable) -> Unit) = postDelayed(object : Runnable{

    override fun run() {

        runnable(this)

    }

}, delayMilis)

然后在调用方,您将获得Runnable对象作为 lambda 参数(仅参数:)it:


hwnd.postDelayed(5000){ 

    // it : Runnable

    hwnd.postDelayed(it, 5000)

}

或者,如果您真的想变得更花哨,请将扩展参数更改为Handler.(Runnable) -> Unit,然后您将能够调用:


hwnd.postDelayed(5000){ 

    // this : Handler, it : Runnable

    postDelayed(it, 5000)

}


查看完整回答
反对 回复 2021-07-29
?
侃侃尔雅

TA贡献1801条经验 获得超15个赞

这是不可能的。你可以参考这个讨论:“这个”在 SAM 中是否可以访问?


this在 lambda 中是指包含类的实例,如果有的话。lambda 在概念上是一个函数,而不是一个类,因此不存在this可以引用的 lambda 实例之类的东西。


可以将 lambda 转换为 SAM 接口的实例这一事实不会改变这一点。有this一个拉姆达取决于是否拉姆达意味着不同的事情变得SAM-转换会非常混乱。


您可以创建一个解决方法(例如在讨论中建议):创建一个扩展函数:


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

    override fun run() = body()

}

那么你可以这样称呼它


hwnd.postDelayed(runnable { hwnd.postDelayed(this, 5000) }, 5000)


查看完整回答
反对 回复 2021-07-29
  • 2 回答
  • 0 关注
  • 126 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信