开发者

how to make a collection of type objects in Scala

开发者 https://www.devze.com 2023-04-10 08:17 出处:网络
Basically, I want to have a Map indexed by type objects. In this case, I\'m trying to use Class as the \"type type\".

Basically, I want to have a Map indexed by type objects. In this case, I'm trying to use Class as the "type type".

the following code:

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

def insertItem1[T <: SuperC开发者_Go百科lass] (item : T) = typemap += classOf[T] -> item
def insertItem2[T <: SuperClass] (item : T) = typemap += item.getClass -> item

does not compile, because (1) classOf[T] is apparently invalid:

error: class type required but T found

and (2) item.getClass is of the wrong type:

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

I see two ways to accomplish this:

either drop the type requirement and use Class[_] only

or use Manifest instead of Class (not sure how to do that yet, any examples are welcome)

But more generally, why is classOf[T] invalid, and how do I obtain a class object for a parametrized type?

update: I found out that I can use item.getClass.asInstanceOf[Class[T]] to get to the class object. For one, this is ugly. For two, it doesn't help much, because later in the code i have functions such as this one:

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

Obviously, I could use the asInstanceOf method in insertItem and pass the class as a parameter to isPresent. Is there a better way?


You can use manifests to achieve this:

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)

You are losing the types through erasure, so you need to add the implicit argument to the putThing which contains the name of the class, using a Manifest.


The problem is once again that generics aren't available at run time. The compiler does the task of figuring out what T is, but it can't because it is only know at run time.

You could use a manifest to obtain that information: What is a Manifest in Scala and when do you need it?.

0

精彩评论

暂无评论...
验证码 换一张
取 消