我发现 Scala 总是对任何事情都有“自然的解释”。总是类似“哦,但这只是用这个和那个参数在这个和那个对象上调用的函数”。从某种意义上说,没有什么是真正像我们从其他语言中了解到的那样具有编译器魔力。
我的问题是关于<-运算符如以下代码中所使用:
for(i <- 0 to 10) println(i)
在这个例子中,我可以看到它被重写为:
0.to(10).foreach((i:Int)=>println(i))
但这并不能解释如何i被带入 foreach 函数内的匿名函数中。在你写的地方i它不是一个对象,也不是一个声明的变量。那么它是什么?它是如何被转移到 foreach 内部的?
我的猜测是我终于发现了一些事实上的东西编译器魔法
谢谢你的时间。
澄清,我的问题是:
为了补充 Dave 的答案,这里有一个来自 Scala 语言规范的“for-commplions”的翻译模式:
一个领悟for (enums) yield e
评估表达式e
对于枚举器 enums 生成的每个绑定。枚举器序列总是以生成器开始;接下来可以是进一步的生成器、值定义或防护。
发电机一台p <- e
从表达式生成绑定e
它以某种方式与模式匹配p
。值定义val p = e
绑定值名称p
(或模式中的多个名称p
) 计算表达式的结果e
。一名警卫if e
包含一个限制枚举绑定的布尔表达式。
生成器和守卫的精确含义是通过转换为调用来定义的
四种方法:map
, filter
, flatMap
, and foreach
。对于不同的运营商类型,可以以不同的方式实施这些方法。
翻译方案如下。第一步,每个生成器p <- e
,其中 p 对于以下类型不是无可辩驳的(第 8.1 节)e
被替换为
p <- e.filter { case p => true; case _ => false }
然后,重复应用以下规则,直到所有理解都已完成
被淘汰。
一个用于理解for (p <- e) yield e0
被翻译成e.map { case p => e0 }
.
一个用于理解for (p <- e) e0
被翻译成e.foreach { case p => e0 }
.
一个用于理解for (p <- e; p0 <- e0 . . .) yield e00
, 在哪里 。 。 。是生成器或守卫的(可能为空)序列,被翻译
到:
e.flatMap { case p => for (p0 <- e0 . . .) yield e00 }
.
一个用于理解for (p <- e; p0 <- e0 . . .) e00
在哪里 。 。 。是一个(可能是空的)生成器或守卫序列,被翻译为:
e.foreach { case p => for (p0 <- e0 . . .) e00 }
.
发电机一台p <- e
后面跟着一名警卫if g
被转换为单个生成器:
p <- e.filter((x1, . . . , xn) => g )
where x1
, . 。 。 ,xn
是自由变量
的p
.
-
发电机一台p <- e
接下来是值定义val p0 = e0
已翻译
到以下值对生成器,其中x
and x0
都是新鲜的名字:
val (p, p0) <-
for(x@p <- e) yield { val x0@p0 = e0; (x, x0) }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)