Scala获取自类型的具体类型

Scala获取自类型的具体类型,scala,types,self-type,Scala,Types,Self Type,我想在self-typetrait中获得对Scala中self-type注释的具体类型的引用。我有这样的想法: trait Foo class FooImpl1 extends Foo class FooImpl2 extends Foo trait SpecialFoo { this:Foo => def |+|(that:this.type):this.type // the type signature is incorrect here } 其中,如果我使用Speci

我想在self-typetrait中获得对Scala中self-type注释的具体类型的引用。我有这样的想法:

trait Foo
class FooImpl1 extends Foo
class FooImpl2 extends Foo

trait SpecialFoo {
  this:Foo =>

  def |+|(that:this.type):this.type // the type signature is incorrect here
}

其中,如果我使用SpecialFoo创建
new FooImpl1
,我希望
+
方法要求并返回
FooImpl1
(或
FooImpl1
的子类型)。但是,对于上面的代码,它似乎需要一个
SpecialFoo.this.type
,这并不奇怪,但不是我想要的。

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 = $anon$1@118102ee

scala> s |+| s2
<console>:14: error: type mismatch;
 found   : Spec
 required: <refinement>.type
       s |+| s2
             ^
不幸的是,您需要编写两次
FooImpl1
,但是self类型仍然阻止您混合使用两种不同的实现

另一种方法是在
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[顺便说一句,阴影
这不是一个好主意
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
}