【问题标题】:How to tell if a Scala reified type extends a certain parent class?如何判断 Scala 实体化类型是否扩展了某个父类?
【发布时间】:2012-02-11 01:16:06
【问题描述】:

在 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

我还缺少另一个技巧吗?

【问题讨论】:

    标签: scala types


    【解决方案1】:

    好的旧反射怎么样:

    def isPerishable[P](implicit m: Manifest[P]): Boolean = 
      classOf[PerishableProduct].isAssignableFrom(m.erasure)
    
    isPerishable[Fridge]   // false
    isPerishable[Banana]   // true
    

    【讨论】:

    • 哇,感谢 Sciss - 这很好用。它甚至适用于带有类型参数的特征:classOf[GroupedPerishableProduct[_]].isAssignableFrom(bananasType)
    【解决方案2】:

    问题是在处理类型擦除时需要清单。清单提供了一种使用 <:> 执行此测试的简单方法

    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 )
    

    【讨论】:

    • 非常感谢Neil - 我之前没有遇到过&lt;:&lt;,它看起来很有用。不幸的是,这对我不起作用 - 因为在比较时我只有 manifestP.erasure.asInstanceOf[Class[P]] 可用,而不是 manifest[P]
    【解决方案3】:

    类似的例子:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-07
      • 2010-10-10
      • 2014-09-17
      • 1970-01-01
      • 2023-03-20
      • 1970-01-01
      相关资源
      最近更新 更多