Scala - 访问参数化类型 class

Scala - Acessing the type of a parameterized class

假设我有一个可以容纳某种动物的盒子。
可以为这个 Box 提供原始数据,这些数据应该 transformed/serialized 变成与 Box 中已有动物相同类型的动物。
换句话说,如果给一盒狗一些 "data",我想验证 "data" 是另一只狗。

trait Animal
trait Dog extends Animal
trait Cat extends Animal   

 class Box[T<:Animal](elems: List[T]) {

      def receiveNewAnimal(data: String): T = validate[T](data)(<implicit val>)
    }

通常,当我想针对特定动物验证 "rawData" 时,我会这样做(例如狗):

val getMyDog(data: String): Dog = validate[Dog](data)

但是,我不知道 Box[T] 装的是哪种动物。
如果我让它保持原样:

def receiveNewAnimal(data: String): T = validate[T](data)(<implicit val>)

我收到一个编译错误,说我没有类型 T 的隐式(即使我有所有可能的 Animal 子特征的隐式)。
看来我无法告诉编译器,我想根据当前 Box 包含的 Animal 类型验证数据。

  1. 为什么会这样?
  2. 能否解决,如何解决?

您必须将隐式值从调用 Box 构造函数的调用站点传输到 validate 方法。


假设有如下类型类:

trait Validatable[T]

并且 validate 要求 TValidatable:

def validate[T : Validatable](serializedData: String): T = ???

你可以这样做:

trait Animal
trait Dog extends Animal
trait Cat extends Animal   

class Box[T <: Animal : Validatable](elems: List[T]) {
  def receiveNewAnimal(data: String): T = validate[T](data)
}

或者,如果您的 validate 是使用第二个参数列表声明的,您可以对 Box:

执行相同的操作
def validate2[T](serializedData: String)(implicit v: Validatable[T]): T = ???

class Box2[T <: Animal](elems: List[T])(implicit v: Validatable[T]) {
  def receiveNewAnimal(data: String): T = validate[T](data)(v)
}

在这种情况下,Validatable 实际上并不是那么重要,可能是一些 ClassTag,可能是一些提供反序列化策略的宏生成的令牌。