Scala - 访问参数化类

时间:2018-04-14 19:23:03

标签: scala generics types implicit-conversion scala-generics

想象一下,我有一个盒子可以容纳某种类型的动物 可以给这个Box提供原始数据,这些数据应该被转换/序列化为与Box中已有的动物相同类型的动物 换句话说,如果给一盒狗带来一些数据",我想验证"数据"是另一只狗。

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>)
    }

通常,当我想验证&#34; rawData&#34;针对特定的动物,我会做(狗的例子):

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

但是,我不知道Box [T]中有哪种类型的动物 如果我按原样:

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

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

  1. 为什么会这样?
  2. 可以解决吗?怎么办?

1 个答案:

答案 0 :(得分:1)

您必须将调用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,可能是某些宏生成的令牌,它提供了一些反序列化策略。