在 Scala 中返回
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12560463/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return in Scala
提问by Jatin
I am a newbie scala programmer and came across a weird behavior.
我是一个新手 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);....
Above basically I want to return true if elem.isEmptyand count == 0. Otherwise, I want to return false.
以上基本上我想返回 true if elem.isEmptyand count == 0。否则,我想返回 false。
Now above I have read that there is no need to add a return statement in scala. So I have omitted returnabove. But it doesn't return the boolean. If I add a return statement as return true. it works perfectly. Why is it so?
现在上面我已经读到不需要在 Scala 中添加 return 语句。所以我return上面省略了。但它不返回布尔值。如果我将 return 语句添加为return true. 它完美地工作。为什么会这样?
Also, why is it considered a bad practice to have return statements in scala
另外,为什么在 Scala 中使用 return 语句被认为是一种不好的做法
回答by dhg
It's not as simple as just omitting the returnkeyword. In Scala, if there is no returnthen the last expression is taken to be the return value. So, if the last expression is what you want to return, then you can omit the returnkeyword. But if what you want to return is notthe last expression, then Scala will not know that you wanted to return it.
这并不像省略return关键字那么简单。在 Scala 中,如果没有,return则将最后一个表达式作为返回值。所以,如果最后一个表达式是你想要返回的,那么你可以省略return关键字。但是如果你想要返回的不是最后一个表达式,那么 Scala不会知道你想要返回它。
An example:
一个例子:
def f() = {
if (something)
"A"
else
"B"
}
Here the last expression of the function fis an if/else expression that evaluates to a String. Since there is no explicit returnmarked, Scala will infer that you wanted to return the result of this if/else expression: a String.
这里函数的最后一个表达式f是一个 if/else 表达式,它的计算结果是一个字符串。由于没有显式return标记,Scala 会推断您想要返回这个 if/else 表达式的结果:一个字符串。
Now, if we add something afterthe if/else expression:
现在,如果我们在 if/else 表达式后添加一些内容:
def f() = {
if (something)
"A"
else
"B"
if (somethingElse)
1
else
2
}
Now the last expression is an if/else expression that evaluates to an Int. So the return type of fwill be Int. If we really wanted it to return the String, then we're in trouble because Scala has no ideathat that's what we intended. Thus, we have to fix it by either storing the String to a variable and returning it after the second if/else expression, or by changing the order so that the String part happens last.
现在最后一个表达式是一个计算结果为 Int 的 if/else 表达式。所以返回类型f将是 Int。如果我们真的想让它返回字符串,那么我们就有麻烦了,因为 Scala不知道这就是我们的意图。因此,我们必须通过将字符串存储到变量并在第二个 if/else 表达式之后返回它来修复它,或者通过更改顺序使字符串部分最后发生。
Finally, we can avoid the returnkeyword even with a nested if-else expression like yours:
最后,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
}
}
}
回答by Grmpfhmbl
This topic is actually a little more complicated as described in the answers so far. This blogpost by Rob Norrisexplains it in more detail and gives examples on when using return will actually break your code (or at least have non-obvious effects).
正如到目前为止的答案中所描述的那样,这个主题实际上要复杂一些。Rob Norris 的这篇博文对其进行了更详细的解释,并提供了有关何时使用 return 会实际破坏您的代码(或至少具有不明显的效果)的示例。
At this point let me just quote the essence of the post. The most important statement is right in the beginning. Print this as a poster and put it to your wall :-)
在这一点上,让我引用帖子的精华。最重要的声明就在开头。将此打印为海报并将其贴在墙上:-)
The
returnkeyword is not “optional” or “inferred”; it changes the meaning of your program, and you should never use it.
该
return关键字是不是“可选的”或“推断”; 它改变了你的程序的意义,你永远不应该使用它。
It gives one example, where it actually breaks something, when you inline a function
它给出了一个例子,当你内联一个函数时,它实际上破坏了某些东西
// 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.
because
因为
A
returnexpression, when evaluated, abandons the current computation and returns to the caller of the method in whichreturnappears.
甲
return表达,评价时,放弃当前计算和返回到其中的方法的调用者return出现。
This is only one of the examples given in the linked post and it's the easiest to understand. There're more and I highly encourage you, to go there, read and understand.
这只是链接帖子中给出的示例之一,它最容易理解。还有更多,我强烈鼓励你去那里阅读并理解。
When you come from imperative languages like Java, this might seem odd at first, but once you get used to this style it will make sense. Let me close with another quote:
当您使用像 Java 这样的命令式语言时,乍一看这可能很奇怪,但是一旦您习惯了这种风格,它就会变得有意义。让我用另一句话结束:
If you find yourself in a situation where you think you want to return early, you need to re-think the way you have defined your computation.
如果您发现自己处于想早点返回的情况,则需要重新考虑定义计算的方式。
回答by jmdeldin
I don't program Scala, but I use another language with implicit returns (Ruby). You have code after your if (elem.isEmpty)block -- the last line of code is what's returned, which is why you're not getting what you're expecting.
我不会编程 Scala,但我使用另一种带有隐式返回的语言 (Ruby)。在if (elem.isEmpty)块之后有代码——最后一行代码是返回的内容,这就是为什么你没有得到你期望的。
EDIT: Here's a simpler way to write your function too. Just use the boolean value of isEmpty and count to return true or false automatically:
编辑:这也是编写函数的一种更简单的方法。只需使用 isEmpty 和 count 的布尔值自动返回真或假:
def balanceMain(elem: List[Char]): Boolean =
{
elem.isEmpty && count == 0
}
回答by Tharabas
By default the last expression of a function will be returned.
In your example there is another expression after the point, where you want your return value.
If you want to return anything prior to your last expression, you still have to use return.
默认情况下,将返回函数的最后一个表达式。在您的示例中,点之后有另一个表达式,您希望返回值。如果您想返回上一个表达式之前的任何内容,您仍然必须使用return.
You could modify your example like this, to return a Booleanfrom the first part
您可以像这样修改您的示例,以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
}
}
回答by Bart Schuller
Don't write ifstatements without a corresponding else. Once you add the elseto your fragment you'll see that your trueand falseare in fact the last expressions of the function.
不要写if没有相应else. 一旦您将else加到您的片段中,您将看到您的true和false实际上是该函数的最后一个表达式。
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....
回答by Zhu Jinxuan
Use case match for early return purpose. It will force you to declare all return branches explicitly, preventing the careless mistake of forgetting to write return somewhere.
用例匹配用于提前返回目的。它会强制你显式声明所有的 return 分支,防止忘记在某处写 return 的粗心错误。

