Lambda被忽略,直到"运行"被添加

时间:2018-03-11 00:51:10

标签: kotlin rx-kotlin2

我有一个通过Retrofit调用API的rx链。我订阅了我的API服务,使用标准的rx subscribe({...})方法并将lambda传递给它。不幸的是,当我的调用最终完成时,我在lambda中执行的所有代码都被完全忽略了。 AndroidStudio提出了一个修复方法,它基本上为我的lamda添加了一个内联函数run并且...它神奇地起作用。我不知道发生了什么。为什么没有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")
                }

            })

2 个答案:

答案 0 :(得分:2)

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

因此,

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

相同
{ data ->
    { ->
        val cs = data.creditReportInfo.score
        view.setCreditScore(cs)
        Logger.getLogger("success:").info("credit score $cs")
    }
}

创建一个lambda表达式,并且不执行任何操作。

你想做的是

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

但这与

相同
{ data ->
    val cs = data.creditReportInfo.score
    view.setCreditScore(cs)
    Logger.getLogger("success:").info("credit score $cs")
}

加上额外的功能创建开销。

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

一样
{ data ->
    run { ->
        val cs = data.creditReportInfo.score
        view.setCreditScore(cs)
        Logger.getLogger("success:").info("credit score $cs")
    }
}

答案 1 :(得分:1)

查看run函数的定义。它是一个简单的内联函数,几乎什么都不做。我用它来分离我在Kotlin的逻辑。

val runResult = run { // 
  // Do something in here that doesn't impact the rest of my algorithm / code
  val a = 1
  val b = 2
  a + b // return a + b
}

// Can't access a or b here. run successfully keeps the rest of my algorithm separate / clean

您还可以使用run方法创建内联属性:

class Example {
  /**
   * Will have the value "0123456789"
   */
  val exampleString: String = run { //
    val sb = StringBuilder()
    for (i in 0..9) {
      sb.append(i)
    }
    sb.toString()
  }
}

现在,据说,run肯定不会影响您的RxJava代码。我建议您清理项目并再次运行。此外,kotlin为具有最后一个参数的lambda的函数提供了更好的语法。如果我写这篇文章,我会用你所写的等价语法编写以下代码:

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