2011-10-02 209 views
2

基本上,我想要一個按類型對象索引的Map。在這種情況下,我試圖使用Class作爲「類型類型」。如何在Scala中創建一個類型對象的集合

以下代碼:

class SuperClass {} 
val typemap = new HashMap[Class[_ <: SuperClass], SuperClass] 

def insertItem1[T <: SuperClass] (item : T) = typemap += classOf[T] -> item 
def insertItem2[T <: SuperClass] (item : T) = typemap += item.getClass -> item 

不編譯的,因爲(1)classOf [T]是明顯無效的:

error: class type required but T found 

和(2)item.getClass是錯誤的類型的:

Type mismatch, expected: Class[_ <: SuperClass], actual: Class[_] 

我看到兩個途徑來實現:
要麼降日e型需求和使用Class [_]僅
或使用清單,而不是類(不知道該怎麼做還沒有任何例子是歡迎)

但更普遍,爲什麼classOf [T]無效,以及如何獲取參數化類型的類對象嗎?

更新:我發現我可以使用item.getClass.asInstanceOf[Class[T]]來到類對象。首先,這是醜陋的。二,它沒有太大的幫助,因爲在後面的代碼我有功能,比如這一個:

def isPresent[T <: SuperClass] = typemap contains classOf[T] 

很顯然,我可以使用asInstanceOf方法insertItem並把類作爲參數傳遞給isPresent。有沒有更好的辦法?

+1

爲什麼你需要按類型存儲和檢索對象?我想知道是否給了更多的上下文,沒有一個不涉及'classOf'或'getClass'的不同解決方案... – huynhjl

+0

我相信這是http://stackoverflow.com/questions/7335946/class-type-as-key-in-map-in-scala – Sohum

+0

@huynhjl usecase是一個實體系統,我希望能夠基本上檢索給定類型的所有(註冊)對象。所以我可以爲每種類型定義一種特殊的鍵,但Class對象是這個鍵。 它可以不做的是泛型,我可以簡單地將Class對象作爲鍵傳遞,然後它將正常工作。但我認爲有更好的辦法。 – matejcik

回答

2

您可以使用清單來實現這一目標:

class TypeMap extends HashMap[Class[_], Any] { 
    def putThing[T](t: T)(implicit m: Manifest[T]) = put(m.erasure, t) 
} 

val map = new TypeMap 
map.putThing(4) 
map.get(classOf[Int]) // returns Option[Any] = Some(4) 

您通過擦除丟失的類型,所以你需要的隱含參數添加到包含類的名稱putThing,使用清單。

+0

我不明白的是,如何通過putThing中的擦除來丟失T - 畢竟,我可以通過't.getClass'來獲取它,所以它必須在運行時被知道。 – matejcik

相關問題