为什么这个“别名”在scala中起作用?

时间:2016-01-31 22:59:37

标签: scala syntax

在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

1 个答案:

答案 0 :(得分:2)

基本机制在this question中处理。这里解决的问题是mapflatMap都需要从新创建的内部引用外部 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
  }
}