【问题标题】:how to make a collection of type objects in Scala如何在 Scala 中创建类型对象的集合
【发布时间】:2011-10-03 20:18:38
【问题描述】:

基本上,我想要一个按类型对象索引的 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 方法并将类作为参数传递给isPresent。有没有更好的办法?

【问题讨论】:

  • 为什么需要按类型存储和检索对象?我想知道是否有更多的上下文,没有不涉及classOfgetClass 的不同解决方案...
  • 我相信这是stackoverflow.com/questions/7335946/…的副本
  • @huynhjl 用例是一个实体系统,基本上我希望能够检索给定类型的所有(注册)对象。所以我可以为每种类型定义一种特殊的键,但是 Class 对象就是那个键。它可以做的是没有泛型,我可以简单地将 Class 对象作为键传递,然后它就可以正常工作了。但我认为有更好的方法。

标签: scala collections type-systems


【解决方案1】:

您可以使用清单来实现:

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)

您正在通过擦除丢失类型,因此您需要使用 Manifest 将隐式参数添加到包含类名称的 putThing。

【讨论】:

  • 我不明白的是 putThing 中的擦除怎么会丢失-毕竟我可以通过t.getClass 得到它,所以它必须在运行时知道。
【解决方案2】:

问题再次是泛型在运行时不可用。编译器完成了找出T 是什么的任务,但它不能,因为它只在运行时知道。

您可以使用清单来获取该信息:What is a Manifest in Scala and when do you need it?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多