KCh*_*oux 3 compiler-construction syntax macros scala
斯卡拉的<-箭似乎有点奇怪.大多数运算符作为函数在源中的某处实现,直接或隐式地在数据类型上定义.<-另一方面,在for理解之外似乎只能使用它,它作为一个句法元素,用于表示一个新变量在monadic上下文中的绑定(via map).
这是我能想到的唯一一个实例,Scala具有一个只能在特定上下文中使用的符合运算符的语法元素,而且不是一个实际的函数.
我错了怎么<-工作?它是仅由编译器使用的特殊情况符号,还是开发人员在编写自己的代码时可以使用此行为?
例如,是否可以编写宏来进行转换
forRange (i <- 0 to 10) { print(i) }
Run Code Online (Sandbox Code Playgroud)
成
{ var i = 0; while (i <= 10) { print(i) } }
Run Code Online (Sandbox Code Playgroud)
而不是它的标准map等价?据我所知,任何上下文i <- ...之外的使用for都会因引用未知值而导致异常.
简而言之,yes <-是Scala中的保留运算符.这是编译器的事情.
的foreach
foreach和之间存在很大的区别for yield,但语法只是语法糖,在编译时转换.
for (i <- 1 to 10) { statement } 表达式被翻译为:
Range.from(1, 10).foreach(..)
Run Code Online (Sandbox Code Playgroud)
多个变量:
for (i <- 1 to 10; y <- 2 to 100) {..}变为:
Range.from(1, 10).foreach(
el => {Range.from(2, 100).foreach(..)});
所有变化由下式给出:
for (x <- someList)= someList.foreach(..).
简而言之,它们都会被foreach陈述为脱脂.foreach调用的具体内容由使用的集合给出.
为了收益
该for yield语法糖flatMap和map.该stay in the monad规则适用于此处.
for (x <- someList) yield {..}被翻译成一个someList.flatMap(..).
链式操作成为map/flatMap组合的分层链:
for {
x <- someList; y <- SomeOtherList
} yield {} 变为:
someList.flatMap(x => {
y.flatMap(..)
}); 等等.
关键点
关键是<-运算符只不过是语法糖来使代码更具可读性,但它总是在编译时被替换.
强调Rob的观点
Rob是其他Scala语法糖的优秀例子.
上下文绑定
package somepackage;
class Test[T : Manifest] {}
Run Code Online (Sandbox Code Playgroud)
实际上翻译为:
class Test[T](implicit evidence: Manifest[T])
作为证明,尝试使用上下文绑定来替换类型:
type TestAlias[T : Manifest] = somepackage.Test // error, the : syntax can't be used..也许很容易看出该: Manifest部件实际上不是一个类型参数.
它更容易打字class Test[T : Manifest]而不是class Test[T](implicit evidence: Manifest[T].