< - 只能由编译器访问

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都会因引用未知值而导致异常.

fla*_*ian 6

简而言之,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语法糖flatMapmap.该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].