我有一个类型层次结构,想要查询实现的查找方法。我没有诉诸asInstanceOf
电话而无法做到这一点。
所以给出一个简单的类型层次结构
trait Vehicle
trait Flying extends Vehicle
class Plane extends Flying
trait Driving extends Vehicle
class Car extends Driving
trait Swimming extends Vehicle
class Boat extends Swimming
我的查找方法就像这样
def findVehicle[V <: Vehicle](implicit tag: TypeTag[V]): Option[V] = {
val v = tag.tpe match {
case t if t =:= typeOf[Flying] => Some(new Plane)
case t if t =:= typeOf[Driving] => Some(new Car)
case t if t =:= typeOf[Swimming] => Some(new Boat)
case _ => None
}
v.map(_.asInstanceOf[V])
}
使用类似的查找
println(findVehicle[Flying]) // Some(Plane@5b7fd935)
是否可以在没有asInstanceOf
的情况下实现这样的查找?
答案 0 :(得分:2)
您可以避免使用TypeTag
并改为使用类型类。
trait Builder[+T] {
def build: Option[T]
}
implicit val flyingBuilder = new Builder[Flying] {
def build = Some(new Plane)
}
implicit val drivingBuilder = new Builder[Driving] {
def build = Some(new Car)
}
implicit val swimmingBuilder = new Builder[Swimming] {
def build = Some(new Boat)
}
implicit val anyBuilder = new Builder[Nothing] {
def build = None
}
def findVehicle[V <: Vehicle](implicit b: Builder[V]): Option[V] = b.build
没有涉及反思,这肯定更具惯用性。
请注意,定义Builder[Nothing]
如何通过返回None
来重现您所获得的相同行为。这不一定是个好主意,因为你现在被迫检查该方法是否能够产生一个值。
如果无法构建所需类型的实例,我宁愿选择编译时错误,而是通过直接从T
返回Option[T]
而不是build
来实现它。 (当然要摆脱Nothing
案例)。