【问题标题】:Find the enclosing f of return in anonymous funcion在匿名函数中找到返回的封闭 f
【发布时间】:2018-04-12 11:32:52
【问题描述】:

在 Scala 语言规范 6.20 返回表达式中,它说: “返回表达式 return e 必须出现在某个封闭的命名方法或函数的主体内。源程序中最内层的封闭命名方法或函数,f...”

这里有一个innermost enclosing f,我想为return找到那个f。但是当涉及到匿名函数时,事情就变得有点复杂了。

示例 1:这里最里面的 f 是f1。在反编译的java代码中,我们可以看到异常被f1捕获。

def main(args: Array[String]) { 
  def f1() { () => return }
}

示例 2:这里最里面的 f 仍然是f1。在反编译的java代码中,我们可以看到异常仍然被f1捕获,尽管从执行视图来看,f2return最里面的封闭f。

def main(args: Array[String]) { 
  def f2(x: Any) { println(x) }
  def f1() { f2(() => return) }
}

也许我们可以说,在 Example2 中,x 并没有真正在 f2 中执行。但这是另一个奇怪的例子。

Example3:这里最里面的f是main,不是map和println。(但是我知道map或者println的class文件不能在这里改。)

def main(args: Array[String]) {
  val list = List(1, 2, 3)
  println(list.map(x => return x * 2))
}

总之,这个innermost enclosing f 似乎就是那个直接包含返回表达式的精确def 的方法。

我说的对吗?

【问题讨论】:

  • 您的问题不清楚。为什么你认为f2 包含returnreturnf1 包围,f1main 包围,f2 甚至没有进入图片。在您的最后一个示例中,只有一个函数main,因此显然它必须是封闭函数,因为没有其他函数。
  • @JörgWMittag Emmmmmm...在最后一个示例中,还有其他方法,例如 println 和 map。Andrey 的“封闭定义”让我很清楚。我太纠结于调用顺序了。无论如何,感谢您对我奇怪的问题的评论。
  • return 不在map 的正文中。 map 的主体甚至没有显示在那里。那里唯一的身体是main's。

标签: scala


【解决方案1】:

是的,你是对的。 “封闭”是指“封闭definition”。

正如您自己所注意到的,它不能指代“封闭方法调用”,因为即使是像以下早期 return 的规范用例这样简单的事情:

def findFirstGreaterZero(as: List[Int]): Option[Int] = {
  for (a <- as) {
    if (a > 0) return Some(a)
  }
  None
}

不起作用,即使这里没有明确的 lambda。 for 将脱糖为(a &lt;- as).foreach{ a =&gt; ... return },如果{ a =&gt; ... return ...} 将“包围”return 关键字,则return 将仅从foreach 的主体的当前调用返回,而不是从方法findFirstGreaterZero,这将使return 几乎无用。

【讨论】:

  • “它不能指代“封闭方法调用””——这从规范谈到“正文”和“源文本”这一事实已经很明显,这两者都是静态句法元素,而不是动态的。
  • “封闭式定义”在这里真的很合适。我被这个例子启发了。我太专注于匿名函数而没有注意到常见的情况。
  • @JörgWMittag 哦,你给了我一个更详细的方式来理解规范。我不是以英语为母语的人,这些细节有时会从我的眼前溜走。
猜你喜欢
  • 1970-01-01
  • 2013-03-29
  • 2011-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-15
相关资源
最近更新 更多