回到斯卡拉

Jat*_*tin 69 scala return

我是一个新手scala程序员,并遇到了一个奇怪的行为.

def balanceMain(elem: List[Char]): Boolean =
  {
    if (elem.isEmpty)
      if (count == 0)
        true;
      else false;

    if (elem.head == '(')
      balanceMain(elem.tail, open, count + 1);....
Run Code Online (Sandbox Code Playgroud)

以上我基本上想要返回true,如果elem.isEmptycount == 0.否则,我想返回false.

现在我已经读过,不需要在scala中添加return语句.所以我return上面省略了.但它不返回布尔值.如果我添加一个return语句return true.它完美地运作.为什么会这样?

另外,为什么在scala中使用return语句被认为是一种不好的做法

dhg*_*dhg 122

这并不像省略return关键字那么简单.在Scala中,如果没有,return那么最后一个表达式将被视为返回值.因此,如果最后一个表达式是您想要返回的,那么您可以省略该return关键字.但是如果你想要返回的内容不是最后一个表达式,那么Scala 就不会知道你想要返回它.

一个例子:

def f() = {
  if (something)
    "A"
  else
    "B"
}
Run Code Online (Sandbox Code Playgroud)

这里函数的最后一个表达式f是if/else表达式,它计算为String.由于没有明确return标记,Scala会推断您想要返回此if/else表达式的结果:String.

现在,如果我们在if/else表达式之后添加一些内容:

def f() = {
  if (something)
    "A"
  else
    "B"

  if (somethingElse)
    1
  else
    2
}
Run Code Online (Sandbox Code Playgroud)

现在,最后一个表达式是一个if/else表达式,其值为Int.所以返回类型f将是Int.如果我们真的希望它返回String,那么我们就会遇到麻烦,因为Scala 不知道那是我们的意图.因此,我们必须通过将String存储到变量并在第二个if/else表达式之后返回它,或者通过更改顺序以使String部分最后发生来修复它.

最后,return即使使用像你这样的嵌套if-else表达式,我们也可以避免关键字:

def f() = {
  if(somethingFirst) {
    if (something)      // Last expression of `if` returns a String
     "A"
    else
     "B"
  }
  else {
    if (somethingElse)
      1
    else
      2

    "C"                // Last expression of `else` returns a String
  }
Run Code Online (Sandbox Code Playgroud)

}

  • 所有众神,谢谢!我在同一个问题上打了好几个小时(也在Coursera上课)并且无法理解为什么需要返回. (2认同)
  • 对于第一个示例,如果添加返回会发生什么。即“返回“A””和“返回“B””? (2认同)

Grm*_*mbl 20

到目前为止,这个主题实际上有点复杂.Rob Norris的这篇博文更详细地解释了它,并举例说明何时使用return实际上会破坏你的代码(或者至少具有非显而易见的效果).

在这一点上,让我引用帖子的精髓.最重要的陈述恰好在一开始.将此打印为海报并将其放在墙上:-)

return关键字是不是"可选的"或"推断"; 它改变了程序的含义,你永远不应该使用它.

它给出了一个例子,当你内联函数时,它实际上会破坏某些东西

// Inline add and addR
def sum(ns: Int*): Int = ns.foldLeft(0)((n, m) => n + m) // inlined add

scala> sum(33, 42, 99)
res2: Int = 174 // alright

def sumR(ns: Int*): Int = ns.foldLeft(0)((n, m) => return n + m) // inlined addR

scala> sumR(33, 42, 99)
res3: Int = 33 // um.
Run Code Online (Sandbox Code Playgroud)

因为

return表达,评价时,放弃当前计算和返回到其中的方法的调用者return出现.

这只是链接帖子中给出的一个例子,它是最容易理解的.还有更多,我非常鼓励你,去那里,阅读和理解.

当你来自像Java这样的命令式语言时,这一开始可能看起来很奇怪,但是一旦你习惯了这种风格它就会有意义.让我结束另一个引用:

如果您发现自己处于想要提前返回的状态,则需要重新考虑定义计算的方式.

  • 我不同意Rob,IMO你不能只在lambda表达式中使用`return`,但这在语言中是一个糟糕的设计选择,代码甚至不应该编译(在python中这可以避免使用`lambda`关键字没有return语句)...在其他情况下,如果你想返回一个值,我没有看到使用`return`的真正问题(并且从方法执行中退出是因为所有语言都使用了返回! ) (10认同)
  • 您可以自由发表意见,但是许多人都同意,在Scala中使用return至少是不好的风格。我敢于找到使用return的Scala官方文档示例。在正式文档中甚至没有对AFAIK进行解释,仅在规范文档中进行了说明(第6.20章)。用马丁·奥德斯基本人(Scala编程)的话来说:“方法的建议样式实际上是避免具有显式的(尤其是多个)返回语句。相反,应将每种方法都视为产生一个返回值的表达式。” 本书的第一版可在线免费获得http://www.artima.com/pins1ed/ (2认同)

jmd*_*din 5

我不使用 Scala 编程,但我使用另一种具有隐式返回的语言(Ruby)。你的if (elem.isEmpty)代码块后面有代码——最后一行代码是返回的内容,这就是为什么你没有得到你所期望的结果。

编辑:这也是编写函数的更简单的方法。只需使用 isEmpty 和 count 的布尔值即可自动返回 true 或 false:

def balanceMain(elem: List[Char]): Boolean =
{
    elem.isEmpty && count == 0
}
Run Code Online (Sandbox Code Playgroud)


Tha*_*bas 5

默认情况下,将返回函数的最后一个表达式。在您的示例中,点之后还有另一个表达式,您希望返回值。如果您想返回上一个表达式之前的任何内容,您仍然必须使用return.

您可以像这样修改您的示例,以Boolean从第一部分返回 a

def balanceMain(elem: List[Char]): Boolean = {
  if (elem.isEmpty) {
    // == is a Boolean resulting function as well, so your can write it this way
    count == 0
  } else {
    // keep the rest in this block, the last value will be returned as well
    if (elem.head == "(") {
      balanceMain(elem.tail, open, count + 1)
    }
    // some more statements
    ...
    // just don't forget your Boolean in the end
    someBoolExpression
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 不是“声明”。“表达” (10认同)