Как получить класс времени выполнения параметризованного Типа с чертой Scala - PullRequest
5 голосов
/ 14 декабря 2010

Я пытаюсь реализовать черту Scala, которая обрабатывает детали взаимодействия с библиотекой Java, которая требует от нас создания

Что я хочу сделать, это что-то вроде:

trait SomeTrait[A] extends JavaAPI {
  def foo = {
    callApi(classOf[A])
  }

  override def bar = {
    foo
  }
}

Обратите внимание, что bar на самом деле переопределяет метод из базового класса, поэтому я не могу изменить его сигнатуру.

Я пробовал несколько вариантов с Манифестами и т. Д., Но не могу заставить это работать. Есть ли способ получить класс времени выполнения параметризованного типа?

Ответы [ 4 ]

10 голосов
/ 14 декабря 2010

Этот аромат должен сделать свое дело:

trait SomeTrait[A] {
  def foo(implicit ev: Manifest[A]) = {
    callApi(ev.erasure)
  }
}

update В какой-то момент манифест должен быть введен с помощью параметра метода. Конструктор был бы хорошим выбором, если бы черты могли их иметь.

На самом деле, они могут! Признак имеет конструктор, с которым он смешивается, поэтому, если вы укажете абстрактный манифест, производные классы должны определить ...

trait SomeTrait {
  def ev: Manifest[_] //abstract
  def foo = println(ev.erasure)
}

//this `ev` provides the implementation, note that it MUST be a val, or var
class Concrete[T](implicit val ev: Manifest[T]) extends SomeTrait

И снова все хорошо.

5 голосов
/ 14 декабря 2010

Вы должны каким-то образом получить манифест, а у черт нет параметров конструктора.Только вы можете сказать, какой компромисс вы хотите сделать.Вот еще один.

trait SomeTrait[A] {
  implicit def manifesto: Manifest[A]

  def foo = println(manifest[A].erasure)
}
object SomeTrait {
  def apply[A: Manifest] : SomeTrait[A] = new SomeTrait[A] { def manifesto = manifest[A] }
}
4 голосов
/ 14 декабря 2010

Из-за стирания типа компилятор не может выяснить, какой тип должен быть в черте .Таким образом, то, что вы хотите, не может быть сделано.Тем не менее, вы можете сделать это классом.Таким образом, компилятор может передать параметр доказательства при создании экземпляра.

class SomeTrait[A](implicit ev: Manifest[A]) extends JavaApi {
  def foo = {
    callApi(ev.erasure)
  }


  override def bar = {
    foo
  }
}
0 голосов
/ 13 марта 2013

Это может быть немного неудобно в вашем коде, но вы можете сделать это

trait SomeTrait[A] extends JavaAPI {
  def objType: Class[A]
  def foo = {
    callApi(objType)
  }

  override def bar = {
    foo
  }
}

object SomeImplementation with SomeTrait[SomeObject] {
  val objType: Class[SomeObject] = classOf[SomeObject]
}

Я знаю, что это немного словесно, но я решил эту проблему именно такЯ надеюсь найти лучшее решение в будущем, но это то, что я использую сейчас.Дайте мне знать, если это вам поможет.

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