繁体   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