返回斯卡拉

我是一个新手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);.... 

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

上面我已经读过,没有必要在scala中添加一个return语句。 所以我省略了上面的return 。 但是它不返回布尔值。 如果我添加一个返回语句作为return true 。 它完美的作品。 为什么这样?

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

这不像仅仅省略return关键字那么简单。 在Scala中,如果没有return那么最后一个expression式就是返回值。 所以,如果最后一个expression式是你想要返回的,那么你可以省略return关键字。 但是如果你想要返回的不是最后一个expression式,那么Scala 就不会知道你想要返回它

一个例子:

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

这里函数f的最后一个expression式是一个if / elseexpression式,其值为一个String。 由于没有明确的return标记,Scala会推断你想返回这个if / elseexpression式的结果:一个string。

现在,如果我们在if / elseexpression式之后添加一些东西:

 def f() = { if (something) "A" else "B" if (somethingElse) 1 else 2 } 

现在最后一个expression式是一个if / elseexpression式,其值为一个Int。 所以f的返回types将是Int。 如果我们真的希望它返回string,那么我们遇到了麻烦,因为Scala 不知道这就是我们的意图。 因此,我们必须通过将string存储到variables并在第二个if / elseexpression式之后返回来修复它,或者通过更改顺序以使string部分最后发生来修复它。

最后,即使嵌套的if-elseexpression式像你的那样,我们也可以避免return关键字:

 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 } 

}

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

在这一点上,我只是引用这篇文章的精髓。 最重要的说法是一开始就是正确的。 以海报的forms打印出来,放到墙上:-)

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. 

因为

returnexpression式在计算时放弃当前的计算并返回给出现return值的方法的调用者。

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

当你来自像Java这样的命令式语言时,这个开始可能看起来很奇怪,但是一旦你习惯了这种风格,这将是有道理的。 让我接下来的另一个报价:

如果您发现自己处于一种您认为想要提前返回的情况,则需要重新考虑您定义计算的方式。

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

编辑:这里有一个更简单的方法来写你的function。 只需使用isEmpty的布尔值并自动计数以返回true或false:

 def balanceMain(elem: List[Char]): Boolean = { elem.isEmpty && count == 0 } 

默认情况下,函数的最后一个语句将被返回。 在你的例子中,在这个点之后还有另外一个语句,你想要返回值。 如果您想在上次陈述之前返回任何东西,您仍然必须使用return

你可以像这样修改你的例子,从第一部分返回一个Boolean

 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 someBoolStatement } } 

不要写没有相应的else语句。 一旦你添加了else到你的片段,你会发现你的truefalse实际上是函数的最后一个expression式。

 def balanceMain(elem: List[Char]): Boolean = { if (elem.isEmpty) if (count == 0) true else false else if (elem.head == '(') balanceMain(elem.tail, open, count + 1) else....