在Coursera课程“反应式编程原理”中,Odersky介绍了这个片段:
trait Generator[+T] {
self => // an alias for ”this”.
def generate: T
def map[S](f: T => S): Generator[S] = new Generator[S] {
def generate = f(self.generate)
}
def flatMap[S](f: T => Generator[S]): Generator[S] = new Generator[S] {
def generate = f(self.generate).generate
}
}
我不太清楚self =>
的事情。为什么它会起作用,为什么我不能val self = this
?
答案 0 :(得分:2)
基本机制在this question中处理。这里解决的问题是map
和flatMap
都需要从新创建的内部引用外部 Generator
Generator
。
如果您在此处写this
而不是self
:
def map[S](f: T => S): Generator[S] = new Generator[S] {
def generate = f(this.generate) // wrong!
}
你不会识别外部实例而是内部实例。 this
总是指最近的"从您使用它的地方看到的类实例。
同样,如果您将方法def self = this
添加到Generator
,则会再次调用内部范围中的错误self
(新生成器具有自己的self
方法现在)。
比较中的别名不是一种方法,它不存在"两次"在代码示例中可以这么说,因此在编写new Generator
时不会发生阴影。
def map[S](f: T => S): Generator[S] = {
val outer = this // capture outer instance, since `this` will change meaning
new Generator[S] {
def generate = f(outer.generate) // refer to the outer instance
}
}