特征中自动推断的泛型类型

时间:2015-05-26 07:18:11

标签: scala generics inheritance

我想要一个通用基类,它可以混合在一些特征中。

是否可以让mixin自动采用基类的泛型类型?

abstract class Base[T] {
  def foo: T = ???
  def bar(value: T): Boolean
}

trait MixinA {
  self: Base[U] => // U should be automatically bound to T of Base[T]
  def bar(value: U): Boolean = false
}

2 个答案:

答案 0 :(得分:1)

您可以使用Base中的抽象类型来实现接近此目的:

abstract class Base[T] {
  type U <: T
  def foo: U = ???
  def bar(value: U): Boolean
}

trait MixinA {
  self: Base[_] =>
  final def bar(value: U): Boolean = false
}

REPL测试:

scala> class Impl extends Base[Int] with MixinA
defined class Impl

scala> val i = new Impl
i: Impl = Impl@7ca5cc9e

scala> val x: Int = i.foo
scala.NotImplementedError: an implementation is missing
  at scala.Predef$.$qmark$qmark$qmark(Predef.scala:225)
  at Base.foo(<console>:9)
  ... 33 elided

正如您所看到的,编译器正确地确定i.fooInt的子类型(具体来说, Int)因此可以是分配给x(这里的例外仅仅是因为你没有实现它的身体)。

答案 1 :(得分:0)

在这种情况下,您需要U作为MixinA的类型参数。

trait MixinA[U] { self: Base[U] => ...

类型参数的方式与函数参数类似,如果声明它们需要从某个地方传递它们(没有魔法)。