Как я создаю экземпляр черты в общем методе в scala?

Я пытаюсь создать экземпляр черты с помощью этого метода

val inst = new Object with MyTrait

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

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

Я, очевидно, испытываю необходимость в декларации, чтобы так или иначе решить проблемы стирания типа, но прежде чем я доберусь до этого, я работаю в к 2 вопросам:

  1. Даже с неявной декларацией, Scala все еще требует, чтобы T были чертой. Как я добавляю ограничение для создания [T] так, чтобы T был чертой?

  2. Если бы я принял решение использовать метод Class.newInstance для создания экземпляра динамично вместо того, чтобы использовать "новый", как я указал бы "с" в "новом Объекте с T"? Действительно ли возможно динамично создать новые конкретные типы смешивания во времени выполнения?

8
задан ACyclic 18 July 2010 в 04:15
поделиться

2 ответа

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

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

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

8
ответ дан 5 December 2019 в 07:10
поделиться

Я не уверен, какова мотивация вашего вопроса, но вы можете рассмотреть возможность передачи фабрики для 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 - возможно ли?».

15
ответ дан 5 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: