Scala ClassManifest вместо Type [T] - PullRequest
2 голосов
/ 16 июня 2011

Следующий код

def httpPost[T: ClassManifest](data: AnyRef): T = {
  val webResource = client.resource("http://localhost..")
  val resp = webResource.post(classOf[ClientResponse], data)
  resp.getEntity(classManifest[T].erasure) //Need classOf[T] here 
}

приводит к ошибке компиляции этого типа

[INFO]  found   : _$1 where type _$1
[INFO]  required: T
[INFO]       resp.getEntity(classManifest[T].erasure)

На основе ответа на Scala classOf для параметра типа выглядитон должен работать.

Метод erasure возвращает java.lang.Class [_], и я предполагаю, что это проблема, поэтому у меня есть два вопроса:

  • Почему класс проявляетсявозвращать экзистенциальный тип, а не просто Class [T] - если это стирание T, то оно всегда будет _ (подчеркивание), потому что T, очевидно, неизвестно, что означает, что его возвращаемое значение не так полезно, как я ожидал.
  • Что мне нужно сделать, чтобы код работал!

Обновление:

Спасибо Ким и Жан-Филиппу за вашеответы.

Ранее я пробовал приведение, поэтому исходная последняя строка была заменена на

val responseData = resp.getEntity(classManifest[T].erasure) //Runtime error
responseData.asInstanceOf[T]

, и это компилируется, но теперь возникает ошибка времени выполнения, потому что методу getEntity передается класс Object, который он не может обработать, потому что этонужен более конкретный тип (для которого у него есть обработчик).Хотя он отложен до времени выполнения, он снова сводится к тому, что метод стирания не дает конкретной информации о типе, и поэтому я подумал, что для решения проблемы необходимо решить встроенный пример.

Ответы [ 3 ]

2 голосов
/ 17 июня 2011

Что-то серьезно не так с этим кодом. В частности:

def httpPost[T: ClassManifest](data: AnyRef): T = {
  val webResource = client.resource("http://localhost..")
  val resp = webResource.post(classOf[ClientResponse], data)
  resp.getEntity(classManifest[T].erasure) //Need classOf[T] here 
}

Как Скала должна знать, что типа T? Вы передаете это явно при вызове httpPost? Я подозреваю, что нет, и именно поэтому erasure возвращает Object для вас.

Что касается того, почему ClassManifest#erasure возвращает Class[_] вместо чего-то еще, я подозреваю, что причина в том, что этот тип используется большинством методов Java, и поскольку Class является инвариантным, если erasure вернул Class[T] тогда вам нужно будет разыграть его, чтобы использовать с этими методами!

0 голосов
/ 16 июня 2011

Я считаю, что экзистенциальный тип возвращается, чтобы прояснить, что каст, который вы, возможно, захотите сделать, - ваша ответственность.Class немного странно: например, Class[List[String]] должен фактически быть напечатан как Class[List[_]], так как он не несет никакой информации о параметризации String List.Актерский состав, предложенный Ким, всегда безопасен, когда T сам по себе не является параметризованным типом.

0 голосов
/ 16 июня 2011

Первый вопрос: понятия не имею ...

Второй вопрос: я думаю, что здесь безопасно бросить.Вы можете использовать foo.asInstanceOf[Class[T]].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...