How do I create an instance of a trait in a generic method in scala?

泪湿孤枕 提交于 2019-11-28 00:04:11

You can't do this (even with a Manifest). The code new Object with T involves creating a new anonymous class representing the combination of Object with T. To pass this to your create function, you would have to generate this new class (with new bytecode) at runtime, and Scala has no facilities for generating a new class at runtime.

One strategy might be to try to transfer the special functionality of the factory method into the class's constructor instead, and then use the constructor directly.

Another possible strategy is to create conversion functions (implicit or otherwise) to the traits you're interested in using with this class.

retronym

I'm not sure what the motivation is for your question, but you could consider passing a factory for T as an implicit parameter. This is known as using type classes or ad-hoc polymorphism.

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]

}

At the other end of the spectrum, you could invoke the compiler at runtime, as detailed in this answer to the question "Dynamic mixin in Scala - is it possible?".

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!