在Scala中提供return
语句是否有任何真正的原因? (除了更加“Java友好”)
答案 0 :(得分:47)
忽略嵌套函数,始终可以使用具有等效计算而不返回的返回替换Scala计算。这个结果可以追溯到“结构化编程”的早期阶段,并且巧妙地称为structured program theorem。
使用嵌套函数,情况会发生变化。 Scala允许您将“返回”放置在嵌套函数系列的深处。当执行返回时,控制跳出所有嵌套函数,进入最内层包含的方法,从中返回(假设该方法实际上仍在执行,否则抛出异常)。这种堆栈展开可以通过异常来完成,但不能通过计算的机械重构来完成(没有嵌套函数可能)。
您实际上想要从嵌套函数内部返回的最常见原因是打破强制性的理解或资源控制块。 (强制执行的主体被转换为嵌套函数,即使它看起来就像一个声明。)
for(i<- 1 to bezillion; j <- i to bezillion+6){
if(expensiveCalculation(i, j)){
return otherExpensiveCalculation(i, j)
}
withExpensiveResource(urlForExpensiveResource){ resource =>
// do a bunch of stuff
if(done) return
//do a bunch of other stuff
if(reallyDoneThisTime) return
//final batch of stuff
}
答案 1 :(得分:26)
提供它是为了适应那些难以或麻烦地将所有控制流路径安排在方法的词法末端收敛的情况。
虽然正如Dave Griffith所说的那样,你可以消除对return
的任何使用,但这样做通常会更加模糊,而不是简单地用明显的return
来缩短执行时间。
也要注意,return
从方法返回,而不是在方法中定义的函数(文字)。
答案 2 :(得分:4)
这是一个例子
这个方法有很多if-else语句来控制流,因为没有返回(这就是我的结果,你可以用你的想象来扩展它)。我从一个现实生活中的例子中把它修改成一个虚拟代码(事实上它比这个长):
没有回复:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
error()
} else {
val condition2 = doSomethingElse()
if (!condition2) {
error()
} else {
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
BadRequest("Coudln't receive receipt")
} else {
reply.hede = initializeHede()
if (reply.hede.isGood) {
success()
} else {
error()
}
}
}
}
}
返回:
def process(request: Request[RawBuffer]): Result = {
if (condition1) {
return error()
}
val condition2 = doSomethingElse()
if (!condition2) {
return error()
}
val reply = doAnotherThing()
if (reply == null) {
Logger.warn("Receipt is null. Send bad request")
return BadRequest("Coudln't receive receipt")
}
reply.hede = initializeHede()
if (reply.hede.isGood)
return success()
return error()
}
在我看来,第二个比第一个更具可读性和可管理性。如果您不使用return语句,缩进深度(格式良好的代码)会深入深入。我不喜欢它。)
答案 3 :(得分:2)
在编写命令式样式代码时,我认为return
是有用的,这通常意味着I / O代码。如果您正在使用纯功能代码,则不需要(也不应该使用)return
。但是使用功能代码,您可能需要懒惰以获得与使用return
可以“提早逃脱”的命令式代码相当的性能。