如何在 Scala 中创建类型对象的集合
基本上,我想要一个按类型对象索引的 Map。在本例中,我尝试使用 Class 作为“类型类型”。
以下代码:
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[_]
我看到两种方法可以实现此目的:
要么放弃类型要求并仅使用 Class[_]
或者使用 Manifest 而不是 Class (还不确定如何做到这一点,欢迎提供任何示例)
但更一般地说,为什么 classOf[T] 无效,以及如何获取参数化类型的类对象?
更新:我发现我可以使用item.getClass.asInstanceOf[Class[T]]
来获取类对象。一方面,这很丑陋。对于两个来说,它没有多大帮助,因为稍后在代码中我有这样的函数:
def isPresent[T <: SuperClass] = typemap contains classOf[T]
显然,我可以在 insertItem
中使用 asInstanceOf 方法并将该类作为参数传递给 存在
。有更好的办法吗?
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 <: SuperClass] (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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用清单来实现此目的:
您将通过擦除丢失类型,因此您需要使用清单将隐式参数添加到包含类名称的 putThing 中。
You can use manifests to achieve this:
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.
问题再次是泛型在运行时不可用。编译器会执行找出
T
是什么的任务,但它不能,因为它只能在运行时知道。您可以使用清单来获取该信息: 什么是 Scala 中的清单以及何时需要它?。
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?.