Dav*_*ith 47
忽略嵌套函数,始终可以使用具有等效计算而不返回的返回替换Scala计算.这个结果可以追溯到"结构化编程"的早期阶段,并且被巧妙地称为结构化程序定理.
使用嵌套函数,情况会发生变化.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
}
Run Code Online (Sandbox Code Playgroud)
Ran*_*ulz 26
提供它是为了适应那些难以或麻烦地将所有控制流动路径布置在方法的词法末端会聚的情况.
虽然正如戴夫格里菲斯所说的那样,你可以消除任何使用return,但这样做通常会更加模糊,而不是简单地用明显的方式缩短执行时间return.
也要注意,return从方法返回,而不是在方法中定义的函数(文字).
这是一个例子
这个方法有很多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()
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
有回报:
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()
}
Run Code Online (Sandbox Code Playgroud)
在我看来,第二个比第一个更具可读性,甚至更易于管理。如果不使用 return 语句,缩进的深度(使用格式良好的代码)会越来越深。我不喜欢它:)