想象一下,我有一个盒子可以容纳某种类型的动物 可以给这个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类型来验证数据。
答案 0 :(得分:1)
您必须将调用Box
构造函数的调用站点中的隐式值传输到validate
方法。
假设有类似下面的类型类:
trait Validatable[T]
且validate
要求T
为Validatable
:
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
,可能是某些宏生成的令牌,它提供了一些反序列化策略。