如何在scala中的泛型方法中创建特征实例?

ACy*_*lic 8 scala instance traits new-operator

我正在尝试使用此方法创建特征实例

val inst = new Object with MyTrait
Run Code Online (Sandbox Code Playgroud)

这很好用,但我想把这个创作转移到生成器函数,即.

object Creator {
  def create[T] : T = new Object with T
}
Run Code Online (Sandbox Code Playgroud)

我显然需要清单以某种方式修复类型擦除问题,但在此之前,我遇到了两个问题:

  1. 即使有一个隐含的清单,Scala仍然要求T是一个特征.如何添加限制来创建[T]以使T成为特征?

  2. 如果我选择使用Class.newInstance方法动态创建实例而不是使用"new",我如何在"new object with T"中指定"with"?是否可以在运行时动态创建新的具体mixin类型?

ret*_*nym 15

我不确定你的问题的动机是什么,但你可以考虑将工厂T作为隐含参数传递.这被称为使用类型类ad-hoc多态.

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]

}
Run Code Online (Sandbox Code Playgroud)

另一方面,你可以在运行时调用编译器,详见答案中的问题"Scala中的动态混合 - 是否可能?".


Ken*_*oom 8

你不能这样做(即使有清单).该代码new Object with T涉及创建一个代表组合的新匿名类Object with T.要将它传递给您的create函数,您必须在运行时生成这个新类(使用新的字节码),并且Scala没有在运行时生成新类的工具.

一种策略可能是尝试将工厂方法的特殊功能转移到类的构造函数中,然后直接使用构造函数.

另一种可能的策略是为您感兴趣使用此类的特征创建转换函数(隐式或其他).