2012-01-15 9 views
1

Scalaでは、Scalaのマニフェストと格納によって、与えられたクラスの型を取得しています。私の質問は、元のクラスが親クラスか他のクラスの子孫であるかどうかを調べるには、その型をどうやって調べるのですか?私は以下のように、理由は型消去のt: Class[MyParentClass]上のパターンマッチを行うことができないように見えますScala reified型が特定の親クラスを拡張しているかどうかを調べるには?

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 

は私が欠けているが、別のトリックですか?

答えて

10

どのように古き良き反射について:

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

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

うわー、ありがとうSciss - 素晴らしい作品です。 'classOf [GroupedPerishableProduct [_]] .isAssignableFrom(bananasType)' –

5

問題は、あなたが型消去を扱っているとき、あなたがマニフェスト必要があるということです。マニフェストは<:<でこのテストを実行する簡単な方法を提供します。

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) 
+0

多くのありがとうございます。Neil ** - 私は '<:<'を直前に見つけていませんでした。残念ながら、これは私にとってはうまくいかないでしょう。比較の時点では、 'manifest [P]'ではなく、 'manifestP.erasure.asInstanceOf [Class [P]]'しか利用できないためです。 –