代码之家  ›  专栏  ›  技术社区  ›  ACyclic

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

  •  7
  • ACyclic  · 技术社区  · 15 年前

    我试图用这个方法创建一个trait的实例

    val inst = new Object with MyTrait
    

    这工作得很好,但我想把这个创建移到一个生成器函数中,即。

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

    很明显,我需要清单来解决类型擦除问题,但在开始之前,我遇到了两个问题:

    1. 即使有一个隐式的显式,Scala仍然要求T是一个特征。我如何添加一个限制来创建T,使T成为一个特征?

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

    2 回复  |  直到 15 年前
        1
  •  8
  •   Ken Bloom    15 年前

    你不能这样做(即使有清单)。代码 new Object with T 包括创建一个新的匿名类,该类表示 Object with T create 函数,则必须在运行时生成这个新类(使用新的字节码),而Scala没有在运行时生成新类的工具。

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

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

        2
  •  15
  •   Community CDub    8 年前

    我不知道你问这个问题的动机是什么,但你可以考虑通过一家工厂来解决这个问题 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

    推荐文章