Как создать экземпляр признака в универсальном методе в Scala? - PullRequest
7 голосов
/ 18 июля 2010

Я пытаюсь создать экземпляр черты, используя этот метод

val inst = new Object with MyTrait

Это хорошо работает, но я бы хотел перенести это создание в функцию генератора, т. Е.

object Creator {
  def create[T] : T = new Object with T
}

Мне, очевидно, понадобится манифест, чтобы каким-то образом решить проблемы с стиранием типов, но прежде чем я доберусь до этого, я отвечу на 2 вопроса:

  1. Дажес неявным манифестом, Скала по-прежнему требует, чтобы Т была чертой.Как добавить ограничение для создания [T], чтобы T был признаком?

  2. Если я решил использовать метод Class.newInstance для динамического создания экземпляра, а не с помощью «new»"Как бы я указал" с "в" новый объект с T "?Можно ли динамически создавать новые типы бетонных смесей во время выполнения?

Ответы [ 2 ]

15 голосов
/ 18 июля 2010

Я не уверен, что мотивация для вашего вопроса, но вы могли бы рассмотреть передачу фабрики для T в качестве неявного параметра.Это известно как использование классов классов или специальный полиморфизм .

object Test extends Application {
  trait Factory[T] {
    def apply: T
  }
  object Factory {
    /**
     * Construct a factory for type `T` that creates a new instance by
     * invoking the by-name parameter `t`
     */
    def apply[T](t: => T): Factory[T] = new Factory[T] {
      def apply = t
    }
  }

  // define a few traits...
  trait T1
  trait T2

  // ...and corresponding instances of the `Factory` type class.
  implicit val T1Factory: Factory[T1] = Factory(new T1{})
  implicit val T2Factory: Factory[T2] = Factory(new T2{})

  // Use a context bound to restrict type parameter T
  // by requiring an implicit parameter of type `Factory[T]`
  def create[T: Factory]: T = implicitly[Factory[T]].apply

  create[T1]
  create[T2]

}

На другом конце спектра вы можете вызывать компилятор во время выполнения,как подробно описано в этом ответе на вопрос «Динамический миксин в Scala - возможно ли это?».

8 голосов
/ 18 июля 2010

Вы не можете сделать это (даже с Манифестом).Код new Object with T включает создание нового анонимного класса, представляющего комбинацию Object with T.Чтобы передать это функции create, вам нужно будет сгенерировать этот новый класс (с новым байт-кодом) во время выполнения, а у Scala нет средств для создания нового класса во время выполнения.

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

Другая возможная стратегия заключается в создании функций преобразования (неявных или иных) для интересующих вас признаков.используя с этим классом.

...