ses*_*ses 1 recursion scala return
我和Scala之间存在一些误解
0还是1?
object Fun extends App {
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) { // when this is true
return 1 // and we are about to return 1, the code goes to the next line
}
foo(list.tail, count + 1) // I know I do not use "return here" ...
count
}
val result = foo( List(1,2,3) )
println ( result ) // 0
}
Run Code Online (Sandbox Code Playgroud)
---编辑:
如果我return在这里使用它会工作"return foo(list.tail, count + 1)'.它不解释(对我来说)为什么"返回1"在上面不起作用.
如果您在下面阅读我的完整说明,那么您的三个问题的答案应该都清楚,但这里有一个简短明了的摘要,方便每个人:
count,其默认值为0-so它返回0并打印0.如果你用count=5它调用它,那么它会打印出来5.(参见println下面的示例.)list空的情况下.如果list非空,则返回count.(再次,请参阅println下面的示例.)以下是Odersky的Scala编程报告(第一版可在线获取):
事实上,推荐的方法样式是避免使用显式的,特别是多个返回语句.相反,将每个方法视为一个表达式,该表达式返回一个值.这种理念将鼓励您将方法设计得非常小,将较大的方法分解为多个较小的方法.另一方面,设计选择取决于设计上下文,而Scala可以轻松编写具有多个显式返回的方法(如果这是您想要的).[链接]
在Scala中,您很少使用return关键字,而是利用表达式中的所有内容将返回值传播回方法的顶级表达式,然后将该结果用作返回值.你能想到的return是更多的东西一样break或者goto,扰乱正常的控制流,可能使你的代码更难推理.
Scala没有像Java这样的语句,而是一切都是表达式,这意味着一切都返回一个值.这就是为什么Scala Unit而不是 - void因为即使是voidJava中的东西需要在Scala中返回一个值的原因之一.以下是有关表达式如何与您的代码相关的一些示例:
1+1是2,结果x.y()是方法调用的返回值.if/ else构造更像Java三元运算符.因此,if (x) y else z相当于x ? y : zJava.if像你使用的孤独是一样的if (x) y else Unit.o.c()返回的内容.您可以使用C/C++中的逗号运算符进行类似的构造:(o.a(), o.b(), o.c()).Java实际上没有这样的东西.return关键字打破在表达正常控制流,从而导致当前方法立即返回给定值.您可以认为它有点像抛出异常,因为它是正常控制流的一个例外,并且因为(如throw关键字)生成的表达式具有类型Nothing.该Nothing类型用于表示永远不返回值的表达式,因此在类型推断期间基本上可以忽略.这是一个简单的例子,显示return结果类型为Nothing:def f(x: Int): Int = {
val nothing: Nothing = { return x }
throw new RuntimeException("Can't reach here.")
}
Run Code Online (Sandbox Code Playgroud)
基于这一切,我们可以查看您的方法,看看发生了什么:
def foo(list:List[Int], count:Int = 0): Int = {
// This block (started by the curly brace on the previous line
// is the top-level expression of this method, therefore its result
// will be used as the result/return value of this method.
if (list.isEmpty) {
return 1 // explicit return (yuck)
}
foo(list.tail, count + 1) // recursive call
count // last statement in block is the result
}
Run Code Online (Sandbox Code Playgroud)
现在您应该能够看到count正在使用您的方法的结果,除非您通过使用中断正常的控制流return.您可以看到它return正在工作,因为foo(List(), 5)返回1.相反,foo(List(0), 5)返回5因为它使用块的结果count作为返回值.如果你尝试,你可以清楚地看到这一点:
println(foo(List())) // prints 1 because list is empty
println(foo(List(), 5)) // prints 1 because list is empty
println(foo(List(0))) // prints 0 because count is 0 (default)
println(foo(List(0), 5)) // prints 5 because count is 5
Run Code Online (Sandbox Code Playgroud)
您应该重构您的方法,以便body是一个表达式的值,返回值只是该表达式的结果.看起来您正在尝试编写一个返回列表中项目数的方法.如果是这样的话,这就是我改变它的方式:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) count
else foo(list.tail, count + 1)
}
Run Code Online (Sandbox Code Playgroud)
以这种方式编写时,在基本情况下(列表为空)它返回当前项目计数,否则它返回列表尾部的递归调用结果count+1.
如果你真的希望它总是返回,1你可以改为将其if (list.isEmpty) 1改为,并且它将始终返回,1因为基本情况将始终返回1.
| 归档时间: |
|
| 查看次数: |
1398 次 |
| 最近记录: |