这是一个非常基本的问题,但我无法在任何地方找到答案。在没有返回值的Scala方法中,如何提前退出方法?
例如,
def printPositiveNumbersSum (n1: Int, n2: Int) = {
if (n1 < 0 || n2 < 0)
// How do I break out of this method here?
println(n1 + n2)
}
尝试在Java中使用return
会引发printPositiveNumbersSum
没有返回类型的错误。
我知道我可以将它作为if-else语句,但是如果有多个条件我想退出该方法并返回其调用者,那么这很快就会变得难以处理。
答案 0 :(得分:5)
您需要从方法中指定单位返回类型
def printPositiveNumbersSum(n1: Int, n2: Int): Unit = {
if (n1 < 0 || n2 < 0)
return
println(n1 + n2)
}
然后它让scala编译器感到高兴。
答案 1 :(得分:2)
基本问题的习惯是比他们看起来更有趣。有几种方法可以解决这个问题,可能值得考虑作为替代方案。但基础是,一切都返回某种类型的值,编译器试图找出该类型是什么。在您的情况下,printPostiveNumbersSum
会返回某种类型的内容。
Unit
表示函数或可执行代码段。这个答案已经提到了。考虑为总和返回Option [Int]。如果验证成功,则返回Some(sum)
,如果失败,则返回None
。然后,调用者可以决定在失败的情况下做什么,可能使用match { case Some(sum)...
构造。
def positiveNumbersSum (n1: Int, n2: Int): Option[Int] = {
if (n1 < 0 || n2 < 0)
None
else Some(n1 + n2)
}
但是在更复杂的情况下,当您可能需要考虑更多规则时,为失败返回原因可能很方便,而不仅仅是返回None
。在这种情况下,我发现Either
方便。您可以指定两种返回类型。同样,调用者可以使用match { case Left(reason)... case Right(sum)...
构造进行区分。
def positiveNumbersSum (n1: Int, n2: Int): Either[String,Int] = {
if (n1 < 0 || n2 < 0)
Left("One of the numbers is negative")
else Right(n1 + n2)
}
答案 2 :(得分:1)
您可以翻转逻辑并避免使用return关键字。
def printPositiveNumbersSum (n1: Int, n2: Int) = {
if (n1 >= 0 && n2 >= 0)
println(n1 + n2)
}
您不应该有一个方法的多个退出点,如果您发现自己遇到此问题,则应重新评估您的解决方案。
scala中的return关键字也有点不直观。如果您有Int
对的列表,并且想要迭代列表,打印所有有效对,则可以编写如下函数:
def printMany(l: List[(Int, Int)]): Unit =
l.foreach { case (n1, n2) =>
if (n1 < 0 || n2 < 0) return
println(n1 + n2)
}
现在,在这种情况下,返回关键字究竟要做什么?如果给出一个列表val l = List((1,1), (2,2), (-1, 2), (5,4))
,它将打印2,4,然后它将停止。 return关键字从整个方法返回,而不是嵌套的lambda。
出于这个原因,最好避免在scala中使用return返回。