【问题标题】:Scala - implicit return value syntax [duplicate]Scala - 隐式返回值语法
【发布时间】:2012-09-16 11:55:25
【问题描述】:

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

【问题讨论】:

标签: scala syntax


【解决方案1】:

您应该阅读答案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,那么它们毫无意义!我必须返回它们!”。 “但最后一行仍然存在!”。 “啊啊啊啊!!!!1!!”。

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

【讨论】:

  • 当编译器或解释器试图猜测真的bad things are happining
  • @om-nom-nom,我可以为您评论中的链接提供代表。 :-) :-)
猜你喜欢
  • 2021-04-20
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 2023-02-22
  • 2020-09-19
相关资源
最近更新 更多