Skip to content

Latest commit

 

History

History
53 lines (35 loc) · 1.65 KB

self_type.adoc

File metadata and controls

53 lines (35 loc) · 1.65 KB

Self Type Annotation

Self Types 可用于表达"依赖(require)"关系,如果其他类要使用这个特质,它应该提供这个特质所依赖的实现。

让我们看看一个例子,其中一个 service 需要一个 Module 提供的其他类型的 service。我们可以用下面的 Self Type 注解表达:

trait Module {
  lazy val serviceInModule = new ServiceInModule
}

trait Service {
  this: Module =>

  def doTheThings() = serviceInModule.doTheThings()
}

第二行 this: Module ⇒ 可以被读作 "I’m a Module"。这看起来和定义一个继承 Module 的特质类似。 那么这与直接继承 Module 有什么区别吗?

当使用 self type 时,这意味其他人要使用 Service 必须在实例化时提供一个 Module 或者 Module 子类型实例:

trait TestingModule extends Module { /*...*/ }

new Service with TestingModule

如果你尝试实例化而不混入所需要的特质,那么就会像下面这样失败:

new Service {}

// class Service cannot be instantiated because it does not conform to its self-type Service with Module
//              new Service {}
//              ^

你还应该记住,使用 self-type 语法时可以指定一个以上的特质。现在让我们来谈谈为什么它叫做 self-type(除了可耻地点头"是的,这样的命名很合理“)。 这是因为一种使用 self-type 的流行方式如下:

class Service {
  self: MongoModule with APIModule =>

  def delegated = self.doTheThings()
}

事实上,你可以使用任何合法标识符(不仅仅是 this 或者 self)然后在你的类中引用它。