簡體   English   中英

scala閉包/匿名函數中的多個返回點

[英]Multiple return points in scala closure/anonymous function

據我所知,Scala中沒有辦法在匿名函數中有多個返回點,即

someList.map((i) => {
    if (i%2 == 0) return i // the early return allows me to avoid the else clause
    doMoreStuffAndReturnSomething(i) // thing of this being a few more ifs and returns
})

引發error: return outside method definition (如果沒有提出這個問題,那么代碼將不起作用,因為我希望它可以工作。)

我可以做的一個解決方法是以下

someList.map({
    def f(i: Int):Int = {
        if (i%2 == 0) return i
        doMoreStuffAndReturnSomething(i)
    }
    f
})

但是,我想知道是否還有另一種“接受”的做法。 也許有可能沒有內部功能的名稱?

(一個用例是在循環中模擬一些有價值的continue構造。)

編輯

請相信我,需要避免使用else語句,因為doMoreStuff部分可能看起來像:

val j = someCalculation(i)
if (j == 0) return 8
val k = needForRecalculation(i)
if (k == j) return 9
finalRecalc(i)
...

當你只有if - else結構時,很容易搞砸了。

當然,在我開頭給出的簡單示例中,使用else更容易。 對不起,我覺得這很清楚。

如果你的匿名函數那么復雜,我會更清楚。 匿名函數不適用於比幾行更復雜的東西。 您可以通過在using方法中聲明它來使其成為私有方法

def myF(i:Int):Int = {
    if (i%2 == 0) return i
    doMoreStuffAndReturnSomething(i)
}
someList.map(myF(_))

這是您的變通方法的變體,但更清潔。 它們都將其保密為本地方法范圍。

在您的代碼注釋中,您寫道您要避免使用else關鍵字,但是恕我直言這完全符合您的要求,甚至兩個字符更短;-)

someList.map((i) => {
    if (i%2 == 0) i else
    doMoreStuffAndReturnSomething(i)
})

您給出的示例很容易通過if語句解決。 這樣做沒有表現或其他處罰。

但是你可能還有其他一些情況,看起來很像

if (test) {
  if (anotherTest) {
    val a = someComputation()
    if (testOf(a)) return otherComputation()
  }
  else if (yetAnotherTest) return whatever()
}
bigComputation()

如果你想避免將if轉換為沒有返回的表單所需的if語句和/或代碼重復的混亂,有幾種方法可以處理這種情況。

有各種各樣的偷偷摸摸的事情可以做OptionEither保持狀態一起流動(與orElsefold ),這樣你只能做的計算需要。

你建議你最好創建一個def。 但只是為了比較,考慮一種Option-wrapping風格:

i => {
  ( if ((i%2)==0) Some(i) 
    else None
  ).getOrElse(doStuffAndReturn(i))
}

在上面的大例子中,這種風格會給出

( if (test) {
    if (anotherTest) {
      val a = someComputation()
      if (testOf(a)) Some(otherComputation()) else None
    }
    else if (yetAnotherTest) Some(whatever())
    else None
}).getOrElse(bigComputation())

就個人而言,我認為它更清晰(並且肯定不會更快),但它是可能的。

我認為匿名函數中返回點的主要問題是匿名函數可能會出現在人們通常不會期望它的地方。 因此,不清楚返回語句實際上屬於哪個閉包。 通過明確要求def - return*對應來解決這個問題。

或者,人們需要圍繞要返回的聲明的警衛。 breakable - break但遺憾的是無法返回值。 一些基於延續的解決方案將能夠實現這一目標,盡管我想等待一些普遍的接受和庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM