2010-07-18 67 views
6

我试图创建一个使用这种方法如何在scala中的泛型方法中创建特征的实例?

val inst = new Object with MyTrait 

这行之有效的性状的实例,但我想在这个移动创建到发电机的功能,即。

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

我显然会需要的清单以某种方式解决类型擦除问题,但之前,我要这个,我要2个问题运行:

  1. 即使有一个隐含的清单,斯卡拉仍然要求T是一个特质。如何添加限制来创建[T],以便T是一个特质?

  2. 如果我选择使用Class.newInstance方法动态创建实例而不是使用“new”,我将如何在“带T的新对象”中指定“with”?是否有可能在运行时动态创建新的混凝土混合类型?

回答

8

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

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

另一个可能的策略是创建转换函数(隐式或其他)到你感兴趣的特性使用这个类。

+0

这似乎是该语言的一个有趣的限制,但我没有看到为什么它无法通过Scala中新的“动态”混合支持修复的原因。特征代码已经作为静态方法提供,所以线性化查找可以在运行时计算,而不是烘焙到类字节码中。那么你只需要添加运行时类型检查,以便“asInstanceOf”起作用。 – ACyclic 2010-07-18 15:03:58

14

我不确定你的问题的动机是什么,但你可以考虑通过一个工厂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] 

} 

在光谱的另一端,你可以在运行时调用编译器,如this answer详细说明这个问题:“在斯卡拉动态混入 - ?有没有可能”。

+0

谢谢,我可能不得不使用这种方法。 我的用例是Java代理。我想写一个可远程使用的图书馆。因此我需要为我所有的类定义接口,因为我想暴露一切,这是一个痛苦。一种解决方案是将所有东西都写成特性,然后我可以免费获得界面定义。创建函数的目的是在代理连接的“具体”一侧实例化一个特征。 – ACyclic 2010-07-18 15:09:18

相关问题