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 类型验证数据。
- 为什么会这样?
- 能否解决,如何解决?
您必须将隐式值从调用 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
,可能是一些提供反序列化策略的宏生成的令牌。
假设我有一个可以容纳某种动物的盒子。
可以为这个 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 类型验证数据。
- 为什么会这样?
- 能否解决,如何解决?
您必须将隐式值从调用 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
,可能是一些提供反序列化策略的宏生成的令牌。