-3

可能重复:
在 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("head of empty list"):

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”不是要评估的表达式,而是返回值。为什么不是这样?

4

1 回答 1

0

您应该在此处阅读答案以获取有关隐式返回的信息,因为您的问题的那部分是完全重复的。

但是我将具体回答您关于“我认为编译器会意识到“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);
}

正如你所提到的,01位并没有真正做任何事情。所以也许这个假设的编译器会说“嘿!我能用这些做的唯一有趣的事情就是返回它们!” 从而使他们返回。我们现在有一个双方都返回的 if/else。换句话说,如果list为空,则返回,如果为空,则返回。所以我们总是返回,函数结束。

可是等等!!if/else 表达式后面还有一行!所以我们假设的编译器会说“嘿!如果我回到这里,那我永远不会执行那行!那行看起来很重要。也许我不应该返回,这样我就可以执行它。” 但随后它意识到“哦,不!如果我不返回0or 1,那么它们毫无意义!我必须返回它们!”。“但最后一行仍然存在!”。“啊啊啊啊!!!!1!!”。

所以也许编译器最好不要试图猜测我们想要什么,而是按照我们告诉它的去做。

于 2012-09-25T01:13:51.897 回答