Scala在匿名函数中返回语句 [英] Scala return statements in anonymous functions

查看:318
本文介绍了Scala在匿名函数中返回语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么一个匿名函数中的显式返回语句(使用 return 关键字)从包含的命名函数返回,而不仅仅是从匿名函数本身返回?

Why does an explicit return statement (one that uses the return keyword) in an anonymous function return from the enclosing named function, and not just from the anonymous function itself?

例如以下程序会导致类型错误:

E.g. the following program results in a type error:

def foo: String = {
  ((x: Integer) => return x)
  "foo"
}

以避免 return 关键字,但我对为什么显式和隐式返回语句在匿名函数中有不同的语义感兴趣。

I know it's recommended to avoid the return keyword, but I'm interested in why the explicit and implicit return statements have a different semantics in anonymous functions.

在以下示例中, m 后的return语句survives已完成执行,并且程序会导致运行时异常。如果匿名函数没有从封闭函数返回,就不可能编译该代码。

In the following example, the return statement "survives" after m has finished executing, and the program results in a run-time exception. If anonymous functions didn't return from the enclosing function, it would not be possible to compile that code.

def main(args: Array[String]) {
  m(3)
}

def m: (Integer => Unit) =
  (x: Integer) => return (y: Integer) => 2


推荐答案

正式地说,返回被定义为总是从最近的封闭命名方法

Formally speaking return is defined as always returning from the nearest enclosing named method


返回表达式return e必须出现在包含命名方法或函数的
的正文中。在源程序f中,最内层的名为
的方法或函数必须具有明确的
声明的结果类型,并且e的类型必须符合它。返回
表达式计算表达式e,并将其值作为
的结果返回。

A return expression return e must occur inside the body of some enclosing named method or function. The innermost enclosing named method or function in a source program, f , must have an explicitly declared result type, and the type of e must conform to it. The return expression evaluates the expression e and returns its value as the result of f . The evaluation of any statements or expressions following the return expression is omitted.

因此,在返回表达式之后的任何语句或表达式
的评估都不会有不同的语义一个lambda。皱纹是,与正常方法不同,从lambda创建的闭包可以逃避对包围方法的调用,并且如果在这样的闭包中有返回,您可以获得异常。

So it doesn't have different semantics in a lambda. The wrinkle is that, unlike a normal method, a closure created from a lambda can escape a call to the enclosing method and you can get an exception if there is a return in such a closure.


如果返回表达式本身是匿名函数的一部分,那么
可能在执行返回表达式之前f的封闭实例已经返回了
。在这种情况下,抛出的
scala.runtime.NonLocalReturnException不会被捕获,并且
会向上传播调用堆栈。

If the return expression is itself part of an anonymous function, it is possible that the enclosing instance of f has already returned before the return expression is executed. In that case, the thrown scala.runtime.NonLocalReturnException will not be caught, and will propagate up the call stack.�

现在,至于为什么。一个较小的原因是审美:lambdas是表达式,并且当表达式及其所有的子表达式具有相同的意义,无论什么嵌套结构,它是很好的。 Neal Gafter在 http://gafter.blogspot.com/2006/08/ tennents-correspondence-principle-and.html

Now, as for "why". One lesser reason is aesthetic: lambdas are expressions and it's nice when an expression and all its subexpression have the same meaning no matter what the nesting structure. Neal Gafter talks about that at http://gafter.blogspot.com/2006/08/tennents-correspondence-principle-and.html

它存在的主要原因是,它允许你轻松模拟常用的控制流形式命令式编程,但仍然允许您将事物抽象为更高阶的函数。作为一个玩具示例,Java的foreach构造(for x:xs {yada;})允许在循环内部返回。 Scala没有语言级别foreach。相反,它把foreach放在库中(不计算for expression没有yield,因为他们只是deugar foreach)。具有非本地返回意味着您可以获取Java foreach并直接翻译为Scala foreach。

The main reason it exists, though, is it allows you to easily simulate forms of control flow commonly used in imperative programming but still allows you to abstract things into higher order functions. As a toy example, Java's foreach construct ("for x :xs { yada; }") allows a return inside the loop. Scala doesn't have a language level foreach. Instead, it puts foreach in the library (not counting "for expression" without yield since they just desugar to foreach). Having a non-local return means you can take a Java foreach and translate directly to a Scala foreach.

BTW,Ruby,Smalltalk和Common Lisp我的头)也有类似的非本地回报。

BTW, Ruby, Smalltalk, and Common Lisp (off the top of my head) also have similar "non-local" returns.

这篇关于Scala在匿名函数中返回语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆