1

我有一个通过改造调用 API 的 rx 链。我订阅了我的 API 服务,使用标准的 rxsubscribe({...})方法并将 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")
                }

            })
4

2 回答 2

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")
    }
}
于 2018-03-11T01:48:44.933 回答
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")
        }
于 2018-03-11T01:43:39.883 回答