在添加“run”之前,Lambda 将被忽略

sha*_*dox 3 kotlin rx-kotlin2

我有一个通过 Retrofit 调用 API 的 rx 链。我使用标准 rx 方法订阅我的 API 服务,subscribe({...})并向其传递 lambda。不幸的是,当我的调用最终完成时,我添加的要在 lambda 内执行的所有代码都被完全忽略。AndroidStudio 建议了一个修复程序,该修复程序基本上run为我的 lamda 添加了一个内联函数,并且......它神奇地工作了。我不知道发生了什么事。为什么没有它就不起作用run?有什么run作用?

代码如下:

valuesServiceApi.getValues()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ data ->
                run { //<- What's this?
                    val cs = data.creditReportInfo.score
                    view.setCreditScore(cs)
                    Logger.getLogger("success:").info("credit score $cs")
                }

            })
Run Code Online (Sandbox Code Playgroud)

Nae*_*mul 7

{ expressions }是 的缩写形式{ -> expressions },它是零参数的函数文字。

所以,

{ data ->
    {
        val cs = data.creditReportInfo.score
        view.setCreditScore(cs)
        Logger.getLogger("success:").info("credit score $cs")
     }
}
Run Code Online (Sandbox Code Playgroud)

是相同的

{ data ->
    { ->
        val cs = data.creditReportInfo.score
        view.setCreditScore(cs)
        Logger.getLogger("success:").info("credit score $cs")
    }
}
Run Code Online (Sandbox Code Playgroud)

它创建了一个 lambda 表达式,并且不对其进行任何操作。

你想做的是

{ data ->
    { ->
        val cs = data.creditReportInfo.score
        view.setCreditScore(cs)
        Logger.getLogger("success:").info("credit score $cs")
    }()
}
Run Code Online (Sandbox Code Playgroud)

但这与

{ data ->
    val cs = data.creditReportInfo.score
    view.setCreditScore(cs)
    Logger.getLogger("success:").info("credit score $cs")
}
Run Code Online (Sandbox Code Playgroud)

加上额外的函数创建开销。

run { ... }{ ... }() 与减去额外的临时函数创建开销相同。所以上面是一样的

{ data ->
    run { ->
        val cs = data.creditReportInfo.score
        view.setCreditScore(cs)
        Logger.getLogger("success:").info("credit score $cs")
    }
}
Run Code Online (Sandbox Code Playgroud)