可能重复:
Return in Scala
我刚刚开始使用Scala,并且遇到了一些我并不理解的行为,我希望stackoverflow社区可以解决一些问题。
使用此测试:
example(1,List(1))
这段代码按照我的预期工作 - 在第二次迭代时返回0:
def example(value: Int, list: List[Int]): Int = {
if (list.isEmpty)
return 0
else
return 1
example(value - list.head, list.tail) + example(value, list.tail);
}
但是,这段代码没有 - 它在第二次迭代时抛出NoSuchElementException(“空列表头”):
def example(value: Int, list: List[Int]): Int = {
if (list.isEmpty)
0
else
1
example(value - list.head, list.tail) + example(value, list.tail);
}
差异似乎是在第二个示例中,Scala假定为“0”,而“1”不是返回值,而是要计算的表达式,因为函数末尾有另一个表达式。由于显式的“return”关键字,第一个示例将按预期返回是有道理的。
但是,考虑到第二个示例中if语句的语法,我认为编译器会认识到“0”不是要计算的表达式,而是返回值。为什么不是这样?
答案 0 :(得分:0)
您应该阅读答案here以获取有关隐式返回的信息,因为您的问题部分完全相同。
但我会特别回答你的观点,“我认为编译器会认识到”0“不是要评估的表达式,而是一个返回值”,因为它是一个有趣的观察结果。
简单的答案是0
是一个表达式...恰好是它的评估非常简单的情况。在决定如何处理代码时,Scala不区分“需要努力的表达式”和“容易表达的表达式”。它只是按照它的方式处理它。
更重要的是,如果Scala编译器确实开始猜测你的意图,那就会变得非常疯狂,并且会让编码变得更具挑战性!
要了解我们不想要这个的原因,让我们看看你发布的代码:
def example(value: Int, list: List[Int]): Int = {
if (list.isEmpty)
0
else
1
example(value - list.head, list.tail) + example(value, list.tail);
}
正如您所提到的,0
和1
位并没有真正做任何事情。所以也许这个假设的编译器会说“嘿!我能做的唯一有趣的事就是归还它们!”从而使他们回归。我们现在有一个双方都返回的if / else。换句话说,如果list
为空,我们会返回,如果它不为空,我们会返回。所以我们总是返回,并且函数结束。
但等等!!在if / else表达式之后还有另一行!所以我们假设的编译器说:“嘿!如果我回到这里,那么我就不会执行那条线了!那条线看起来非常重要。也许我不应该返回,这样我才能执行它“。但后来它意识到“哦不!如果我不归还0
或1
,那么它们毫无意义!我必须归还它们!”。 “但最后一行仍在那里!” “Ahhhhhhh !!!! 1 !!”。
所以也许编译器不会试图猜测我们想要什么,而只是做我们告诉它的事情。