как сделать коллекцию объектов типа в Scala - PullRequest
2 голосов
/ 03 октября 2011

По сути, я хочу, чтобы карта была проиндексирована по типам объектов. В этом случае я пытаюсь использовать Class как «тип type».

следующий код:

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[_]

Я вижу два способа сделать это:
либо отбросьте требование типа и используйте только класс [_]
или используйте Manifest вместо Class (пока не знаете, как это сделать, любые примеры приветствуются)

Но в более общем смысле, почему classOf [T] недопустим и как получить объект класса для параметризованного типа?

обновление: Я обнаружил, что могу использовать item.getClass.asInstanceOf[Class[T]], чтобы добраться до объекта класса. Во-первых, это безобразно. Для двоих это не сильно помогает, потому что позже в коде у меня есть такие функции:

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

Очевидно, я мог бы использовать метод asInstanceOf в insertItem и передать класс в качестве параметра isPresent. Есть ли лучший способ?

Ответы [ 2 ]

2 голосов
/ 03 октября 2011

Вы можете использовать манифесты для достижения этой цели:

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, который содержит имя класса, используя Manifest.

1 голос
/ 03 октября 2011

Проблема еще раз в том, что генерики не доступны во время выполнения. Компилятор выполняет задачу выяснения, что такое T, но не может, потому что это известно только во время выполнения.

Вы можете использовать манифест для получения этой информации: Что такое манифест в Scala и когда он вам нужен? .

...