我正在使用Scala 2.10,我有一种情况,我有一个从反射加载的类序列,像这样:
val names = Seq("Foo", "Bar", "Baz")
val classes = names map Class.forName
(在实际问题中,我从一个目录递归地加载了几个类。)
假设层次结构是这样的:
class A
class B
class C
trait D
class Foo extends A
class Bar extends B
class Baz extends C with D
我很清楚类型擦除,所以我不知道我现在应该走哪条路。既然classes
现在是Seq[Class[_ <: Any]]
的类型,我该怎么做来匹配这些类,包括从subiting ?
例如,我想这样做:
classes match { i =>
case /* A */ => println("i inherits from A") // should match Foo
case /* B */ => println("i inherits from B") // should match Bar
case /* D */ => println("i has D trait") // should match Baz
};
我怎么才能做到呢?
使用Class.isAssignableFrom
。例如:
val some = classOf[Some[_]] // subclass
val option = classOf[Option[_]] // superclass
val product = classOf[Product] // trait
option.isAssignableFrom(some) // true, because Some is subclass of Option
some.isAssignableFrom(option) // false, because Option is the superclass
product.isAssignableFrom(some) // true, because Some implements Product
您甚至可以创建用于match
的自定义提取器:
class ClassMatcher(clazz: Class[_]) {
def unapply(clazz2: Class[_]) = clazz.isAssignableFrom(clazz2)
}
object OptionSubType extends ClassMatcher(classOf[Option[_]])
classOf[Some[_]] match {
case OptionSubType() => println("Some is a subtype of Option")
}