2012-01-15 197 views
1

在Scala中,我通過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 

是否有另一種伎倆我失蹤?

回答

10

如何好老的反思:

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

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

謝謝謝斯 - 這個作品很棒。它甚至適用於帶有類型參數的特徵:'classOf [GroupedPerishableProduct [_]]。isAssignableFrom(bananasType)' – 2012-01-16 08:30:04

5

的問題是,當您正在處理的類型擦除需要清單。 Manifest提供了一個簡單的方法來執行此測試<:<。

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 ** - 我以前沒有遇到過'<:',它看起來非常有用。不幸的是,這對我不起作用 - 因爲在比較的時候,我只有'manifestP.erasure.asInstanceOf [Class [P]]'可用,而不是'manifest [P]'。 – 2012-01-16 08:06:57

相關問題