我正在尝试使用此方法创建特征实例
val inst = new Object with MyTrait
这很好用,但我想把这个创作转移到生成器函数,即
object Creator {
def create[T] : T = new Object with T
}
我显然需要清单以某种方式修复类型擦除问题,但在此之前,我遇到了两个问题:
即使有隐式清单,Scala仍然要求T是一个特征。如何添加限制以创建[T]以使T成为特征?
如果我选择使用Class.newInstance方法动态创建实例而不是使用“new”,我如何在“new object with T”中指定“with”?是否可以在运行时动态创建新的具体mixin类型?
答案 0 :(得分: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]
}
另一方面,您可以在运行时调用编译器,详见this answer中的问题“Scala中的动态混合 - 是否可能?”。
答案 1 :(得分:8)
你不能这样做(即使是Manifest)。代码new Object with T
涉及创建表示Object with T
组合的新匿名类。要将它传递给create
函数,您必须在运行时生成这个新类(使用新的字节码),并且Scala没有在运行时生成新类的工具。
一种策略可能是尝试将工厂方法的特殊功能转移到类的构造函数中,然后直接使用构造函数。
另一种可能的策略是为您感兴趣使用此类的特征创建转换函数(隐式或其他)。