【问题标题】:Using return inside a lambda?在 lambda 中使用 return?
【发布时间】:2017-07-27 10:57:56
【问题描述】:

在下面的代码中,如果trips为空,我想显示我的空视图,然后返回并避免运行下面的代码,但是编译器说“这里不允许返回”。

mainRepo.fetchUpcomingTrips { trips ->
    if (trips.isEmpty()) {
        showEmptyViews()
        return
    }

    // run some code if it's not empty
}

有没有办法这样返回?

我知道我可以把它放在 if else 块中,但我讨厌写 if else 的,在我看来,当有更多条件时,它不太容易理解/可读。

【问题讨论】:

    标签: lambda kotlin


    【解决方案1】:

    只需使用合格的返回语法:return@fetchUpcomingTrips

    在 Kotlin 中,lambda 中的 return 表示从最内层的嵌套 fun 返回(忽略 lambda),并且不允许在不是 inlined 的 lambda 中返回。

    return@label 语法用于指定返回的范围。您可以使用 lambda 传递给的函数的名称 (fetchUpcomingTrips) 作为标签:

    mainRepo.fetchUpcomingTrips { trips ->
        if (trips.isEmpty()) {
            showEmptyViews()
            return@fetchUpcomingTrips 
        }
    
        // ...
    }
    

    相关:

    【讨论】:

    • 为什么在 lambda 中不允许返回?我不明白为什么它会被明确禁止。
    • @EmilS。非内联 lambda 可能不会就地调用,而是包装到传递给其他函数的实例中,然后调用,甚至可能在不同的线程上调用。在这种情况下,不合格的return(意思是'从最近的fun返回')无法工作。
    【解决方案2】:

    您也可以将{ trips ->替换为fun(trips) {,组成一个anonymous function,可以正常使用return

    【讨论】:

      【解决方案3】:

      Plain return 建议你从函数中返回。由于您不能从 lambda 中的函数返回,编译器会抱怨。相反,您想从 lambda 返回,并且必须使用标签:

      mainRepo.fetchUpcomingTrips { trips ->
          if (trips.isEmpty()) {
              showEmptyViews()
              return@fetchUpcomingTrips
          }
      
          //run some code if it's not empty
      }
      

      【讨论】:

        【解决方案4】:

        return 的替代方案可能是

        mainRepo.fetchUpcomingTrips { trips ->
                    if (trips.isEmpty())
                        showEmptyViews()
                    else {
                        //run some code if it's not empty
                    }
                }
        

        【讨论】:

          【解决方案5】:

          返回允许我们从外部函数返回。最重要的用例是从 lambda 表达式返回

          匿名函数中的 return 语句将从匿名函数本身返回。

          fun foo() {
              ints.forEach(fun(value: Int) {
                  if (value == 0) return  // local return to the caller of the anonymous fun, i.e. the forEach loop
                  print(value)
              })
          }
          

          当返回一个值时,解析器优先考虑合格的返回,即

          return@a 1
          

          表示“在标签 @a 处返回 1”,而不是“返回带标签的表达式 (@a 1)”。

          返回默认从最近的封闭函数或匿名函数返回。

          Break终止最近的封闭循环。

          继续进入最近的封闭循环的下一步。

          更多详情请参考Returns and Jumps,Break and Continue Labels

          【讨论】:

            【解决方案6】:

            你可以Return to Labels:

            fun foo() {
                listOf(1, 2, 3, 4, 5).forEach lit@{
                    if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
                    print(it)
                }
                print(" done with explicit label")
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-03-19
              • 2012-07-04
              • 2022-12-01
              • 1970-01-01
              相关资源
              最近更新 更多