使用v。不使用`self`类型

时间:2015-07-22 12:56:24

标签: scala

鉴于以下特征:

scala> trait Foo { self => 
     |   def f: String = self.getClass.getName
     | }
defined trait Foo

scala> trait Bar { 
     |  def f: String = this.getClass.getName
     | }
defined trait Bar

然后制作扩展它们的类:

scala> class FooImpl extends Foo {} 
defined class FooImpl

scala> class BarImpl extends Bar {}
defined class BarImpl

然后在新实例上调用他们的f方法:

scala> (new FooImpl).f
res1: String = FooImpl

scala> (new BarImpl).f
res4: String = BarImpl

REPL显示他们打印出相同的值 - 班级名称。

也许这不是一个很好的例子。但是,使用self与使用Foo的{​​{1}}相比,使用Bar的区别是什么?

3 个答案:

答案 0 :(得分:5)

在您的情况下,没有任何区别 - 您只需使用this的其他名称。当您需要消除不同this之间的歧义时,自我类型很有用。例如:

abstract class Foo { self =>
  def bar: Int
  def qux = new Foo {
    def bar = self.bar
  }
}

如果我们在这里写def bar = this.bar,编译器会抱怨我们对bar的定义只是递归调用自身,因为this将引用{{1}的匿名子类我们在Foo中定义,而不是外部qux

答案 1 :(得分:3)

没有区别。 Foo只是self的别名。它唯一会产生影响的是你试图在内部类或特征或某种对象中引用它们。 e.g:

this

答案 2 :(得分:2)

在引用的案例中,基本上没有,正如其他答案所述。

使用自我类型主要为您提供进一步定义特质扩展器类型的机会,例如您提供:

self: Boing =>

其中

trait Boing {
    def x
}

然后self.x中的Foo将在语法上有效,而this.x将无法编译。

(但请注意,你也可以用同样的方式改进this,不需要显式的自我类型标识符)