简体   繁体   English

修复自我类型中的抽象类型

[英]Fixing abstract types in self type

Consider this: 考虑一下:

object TypeProblem {

  trait A {
    type T
    val set = Set[T]()
  }

  trait B {
    def b()
  }

  trait FooBad { this: A =>
    type T <: B
    def x {
      set.foreach(_.b())
    }
  }

  trait FooOk { this: A =>
    type MyT <: B
    type T = MyT

    def x {
      set.foreach(_.b())
    }
  }

}

The compiler complains that value b is not a member of FooBad.this.T So why does FooOk work where I define a new type MyT and assigning T to MyT? 编译器抱怨值b不是FooBad.this.T的成员那么为什么FooOk在我定义新类型MyT并将T分配给MyT的地方工作?

The self type of FooBad is expanded by the compiler to FooBad with A (so that you can still access the members you define yourself). FooBad的自我类型由编译器扩展为FooBad with A (这样您仍然可以访问自己定义的成员)。 That means that T gets the definition in A , and not the one in FooBad , as you'd expect. 这意味着T得到A的定义,而不是FooBad中的FooBad ,正如您所期望的那样。 You can fix your code by changing the definition of FooBad to explicitly add your own type: 您可以通过更改FooBad的定义来明确添加自己的类型来修复代码:

trait FooBad { this: A with FooBad =>
   ..
}

or even better by using subclassing 甚至更好地使用子类化

trait FooBad extends A {
  ..
}

It is my belief that in most cases self-types should be replaced by plain subclassing. 我相信在大多数情况下,自我类型应该用简单的子类来代替。 It is simpler to understand, less scary, and leads to better encapsulation. 它更容易理解,更不可怕,并导致更好的封装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM