如何判断Scala reified类型是否扩展了某个父类?

时间:2012-01-15 23:14:21

标签: scala types

在Scala中,我通过Scala清单抓取给定类的类型并存储它。我的问题是,如何检查该类型以查看原始类是来自一个父类还是另一个类?

由于类型擦除,我似乎无法在t: Class[MyParentClass]上执行模式匹配,如下所示:

trait Product
trait PerishableProduct extends Product

class Fridge extends Product
class Banana extends PerishableProduct

def getProductType[P <: Product](implicit manifestP: Manifest[P]): Class[P] =
  manifestP.erasure.asInstanceOf[Class[P]]

val isPerishable = getProductType[Fridge] match {
  case x: Class[PerishableProduct] => true
  case _ => false
}
// ^^ warning: non variable type-argument PerishableProduct in type pattern
// Class[PerishableProduct] is unchecked since it is eliminated by erasure

我还缺少另一种技巧吗?

3 个答案:

答案 0 :(得分:10)

旧的反思如何:

def isPerishable[P](implicit m: Manifest[P]): Boolean = 
  classOf[PerishableProduct].isAssignableFrom(m.erasure)

isPerishable[Fridge]   // false
isPerishable[Banana]   // true

答案 1 :(得分:5)

问题是你在处理类型擦除时需要清单。 Manifest提供了一种使用&lt;:&lt;。

执行此测试的简便方法
println( manifest[Fridge] <:< manifest[PerishableProduct] )
println( manifest[Banana] <:< manifest[PerishableProduct] )

上面有直接类型引用,所以要更新getProductType,但是会使用它。

def getProductType[P <: Product](implicit manifestP: Manifest[P]): Manifest[P] = manifestP
val isPerishable = getProductType[Fridge] <:< manifest[PerishableProduct]
println( isPerishable )

答案 2 :(得分:0)

类似的例子:

import org.apache.spark.sql.types.{FloatType, IntegerType, NumericType, StringType}

object test_subclass {
  def main(args: Array[String]) = {
    Seq(IntegerType, FloatType, StringType)
      .map(e => {
        e match {
          case _:NumericType => 1
          case _ => 0
        }
      })
      .foreach(println)
  }
}

输出:

1
1
0