【问题标题】:Getting an interface reference inside a lambda function在 lambda 函数中获取接口引用
【发布时间】:2018-08-17 18:36:51
【问题描述】:

考虑以下代码:

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

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

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

这可能吗?

【问题讨论】:

    标签: java android lambda kotlin functional-interface


    【解决方案1】:

    由于默认 lambda 转换为您提供签名为 () -> Unit 的 lambda,这意味着底层 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)
    }
    

    【讨论】:

      【解决方案2】:

      这是不可能的。您可以参考this discussionSAM 中是否可以访问“this”?

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

      可以将 lambda 转换为 SAM 实例的事实 界面不会改变这一点。在 lambda 中包含 this 意味着不同 取决于 lambda 是否进行 SAM 转换的事情将是 非常混乱。

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

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

      那么你可以这样称呼它

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

      【讨论】:

        【解决方案3】:

        你指的是这里描述的“合格这个”:

        https://kotlinlang.org/docs/reference/this-expressions.html

        【讨论】:

          猜你喜欢
          • 2021-05-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-28
          • 2019-01-20
          • 2021-05-06
          • 2017-03-26
          • 1970-01-01
          相关资源
          最近更新 更多