【问题标题】:Why does this "aliasing" work in scala?为什么这种“别名”在scala中起作用?
【发布时间】:2016-01-31 22:59:37
【问题描述】:

在 Coursera 课程“反应式编程原理”中,Odersky 介绍了这个 sn-p:

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

【问题讨论】:

    标签: scala syntax


    【解决方案1】:

    基本机制在this question中处理。这里要解决的问题是,在 mapflatMap 中,您都需要从新创建的 inner @987654325 中引用 outer Generator @.

    如果你在这里写this 而不是self

    def map[S](f: T => S): Generator[S] = new Generator[S] {
      def generate = f(this.generate) // wrong!
    }
    

    您不会识别外部实例,而是内部实例。 this 总是指从你使用它的地方看到的“最接近”的类实例。

    类似地,如果您在Generator 中添加了一个方法def self = this,那么您会在内部范围内再次调用错误的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
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-23
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多