Scala - 隐式返回值语法

时间:2012-09-25 01:03:17

标签: scala syntax

  

可能重复:
  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”不是要计算的表达式,而是返回值。为什么不是这样?

1 个答案:

答案 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);
}

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

但等等!!在if / else表达式之后还有另一行!所以我们假设的编译器说:“嘿!如果我回到这里,那么我就不会执行那条线了!那条线看起来非常重要。也许我不应该返回,这样我才能执行它“。但后来它意识到“哦不!如果我不归还01,那么它们毫无意义!我必须归还它们!”。 “但最后一行仍在那里!” “Ahhhhhhh !!!! 1 !!”。

所以也许编译器不会试图猜测我们想要什么,而只是做我们告诉它的事情。