this.type
是您拥有SpecialFoo
的任何实例的单例类型。根据定义,|+|
只能够自行调用。例如:
trait Spec { def |+|(that: this.type): this.type = that }
val s = new Spec {}
val s2 = new Spec {}
scala> s |+| s
res1: <refinement>.type = [email protected]
scala> s |+| s2
<console>:14: error: type mismatch;
found : Spec
required: <refinement>.type
s |+| s2
^
this.type
是FooImpl1
在某些情况下,但是编译器无法知道的方式。您需要某种方法来捕获更精细的类型FooImpl1
或FooImpl2
。自我类型this: Foo =>
只关心它是一个Foo
。有几种可能性,但都不会像你想要的那么好。
可以参数SpecialFoo
:
trait Foo
class FooImpl1 extends Foo
class FooImpl2 extends Foo
trait SpecialFoo[A <: Foo] { self: A =>
def |+|(that: A): A
}
val foo = new FooImpl1 with SpecialFoo[FooImpl1] {
def |+|(that: FooImpl1): FooImpl1 = that
}
Unforunately,你需要写FooImpl1
两次,但自型还是阻止你混合两种不同的实现。
的替代方法是使用内Foo
类型成员。你不会创建SpecialFoo
时指定两次实现类型,但会创建自己的实现时绑定正确的类型。
trait Foo { type S }
class FooImpl1 extends Foo { type S = FooImpl1 }
class FooImpl2 extends Foo { type S = FooImpl2 }
trait SpecialFoo { self: Foo =>
def |+|(that: self.S): self.S
}
val foo = new FooImpl1 with SpecialFoo {
def |+|(that: FooImpl1): FooImpl1 = that
}
你也可以将Foo
F-界,即trait Foo[A <: Foo]
,并做一些类似上述例子的东西。
BTW阴影'this'是不是一个好主意 – cchantep