返回斯卡拉
我是一个新手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.isEmpty
和count == 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.
因为
return
expression式在计算时放弃当前的计算并返回给出现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
到你的片段,你会发现你的true
和false
实际上是函数的最后一个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....