运维开发网

scala self type trait instantiation

运维开发网 https://www.qedev.com 2020-08-01 08:43 出处:网络 作者:运维开发网整理
scala中的特征类似于 Java或抽象类中的接口.因此,不可能直接从特征中获取实例.但是,我找到了一种实例化特征的方法.这是我做的: trait B { def bId = 1 } trait A { self: B => def aId = 2 } val a = new A with B // The type of a is "A with B", a's value is $
scala中的特征类似于 Java或抽象类中的接口.因此,不可能直接从特征中获取实例.但是,我找到了一种实例化特征的方法.这是我做的:

trait B {
  def bId = 1
}

trait A { self: B =>
  def aId = 2
}

val a = new A with B // The type of a is "A with B", a's value is $anon$1@6ad16c5d

以下内容:

trait User {
  def name: String
}

trait DummyUser extends User {
  override def name: String = "foo"
}

trait Tweeter { self: User =>
  def tweet(msg: String) = println(s"$name: $msg")
}

val t = new Tweeter with User // This doesn't compile
val t = new Tweeter with User with DummyUser // This does work!
// t: Tweeter with User with DummyUser = $anon$1@72976b4
t.tweet("hello")  // result is: "foo: hello"

这两段代码都在使用Scala 2.12.在所有这些中,只有特征!完全没有课.

特质如何以这种方式运作?

这个实例化就像Java的 Anonymous Classes实例化一样,所以当新的Tweeter with User它实际上为Tweeter创建了一个带有用户匿名类的新匿名实例.

并且新的Tweeter with User不能编译,因为它丢失了name方法的实现.实际上你需要实现它像:

val t = new Tweeter with User {
    override def name: String = "hello world"
  }

对于带有DummyUser用户的新Tweeter,您只需要将其声明为带有DummyUser的新Tweeter,因为DummyUser是User的子类型.

在Scala中有一个关于如何使用self类型实现依赖注入的cake pattern.

0

精彩评论

暂无评论...
验证码 换一张
取 消