2011-10-02 210 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

相关问题