在Scala上通过继承匹配类(来自反射)



我正在使用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")
}

相关内容

  • 没有找到相关文章

最新更新