Scala classOf для параметра типу


80

Я намагаюся створити загальний метод для оновлення об'єктів за допомогою scala / java, але я не можу отримати клас для параметра type.

Ось мій код:

object WorkUnitController extends Controller {     
 def updateObject[T](toUpdate: T, body: JsonObject){
  val source = gson.fromJson(body, classOf[T]);
  ...
 }
}

Я отримую помилку

потрібен тип класу, але знайдено T

Я знаю, що в Java ви цього не можете зробити, але чи можливо це взагалі у Scala?

Дякую!


Дивіться також: issues.scala-lang.org/browse/SI-5722
soc

Відповіді:


93

З маніфесту є застарілим (Оскільки Scala 2.10.0) це оновлений відповідь -

import scala.reflect.ClassTag
import scala.reflect._

object WorkUnitController extends Controller {
  def updateObject[T: ClassTag](toUpdate: T, body: JsonObject){
    val source = gson.fromJson(body, classTag[T].runtimeClass)
    ???
  }
}

Ви повинні використовувати ClassTagзамість ClassManifest і .runtimeClassзамість.erasure

Оригінальна відповідь - так, ви можете це зробити, використовуючи маніфести:

object WorkUnitController extends Controller {     
 def updateObject[T: ClassManifest](toUpdate: T, body: JsonObject){
  val source = gson.fromJson(body, classManifest[T].erasure);
  ...
 }
}

О боже, це дивно! Я хотів би знати про це раніше!
Darkzaelus

1
Ви навіть можете писати manifest[T]замість implicitly[Manifest[T]].
Jean-Philippe Pellet

1
@ mericano1 вони стали невід'ємною частиною мови, і, я думаю, Маніфести вже не є експериментальною особливістю
Василь Ременюк

12
@ mericano1 Одне оновлення: Manifestі ClassManifestтепер вони застаріли, замінивши їх на Scala 2.10 TypeTagі ClassTag, відповідно ,.
Daniel C. Sobral

9
Замість того, щоб classTag[T].runtimeClassмені було потрібно classTag[T].runtimeClass.asInstanceOf[Class[T]]. Хтось знає чому?
kosii

6

Відповідь Василя та Максима мені допомогла.

Особисто я віддаю перевагу синтаксису, де implicitвикористовується для додавання таких параметрів (представлений : ClassTag- це скорочення для нього. Тож тут, на випадок, якщо хтось також вважає це кращим способом:

import scala.reflect.ClassTag

object WorkUnitController extends Controller {
  def updateObject[T](toUpdate: T, body: JsonObject)(implicit tag: ClassTag[T]){
    val source = gson.fromJson(body, tag.runtimeClass)
    ???
  }
}

Застереження: Я не компілював вищезазначене, але мій власний подібний код працює таким чином.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.