8

このメソッドを使用して特性のインスタンスを作成しようとしています

val inst = new Object with MyTrait

これはうまくいきますが、この作成をジェネレーター関数に移動したいと思います。

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

型消去の問題をどうにかして修正するためにマニフェストが必要なのは明らかですが、これに到達する前に、2 つの質問に出くわします。

  1. 暗黙のマニフェストがあっても、Scala は T がトレイトであることを要求します。T がトレイトになるように create[T] に制限を追加するにはどうすればよいですか?

  2. "new" を使用するのではなく、Class.newInstance メソッドを使用してインスタンスを動的に作成することを選択した場合、"new Object with T" で "with" をどのように指定しますか? 実行時に新しい具体的な mixin タイプを動的に作成することは可能ですか?

4

2 に答える 2

15

あなたの質問の動機が何であるかはわかりませんが、ファクトリを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]

}

スペクトルの反対側では、 「Scala での動的 mixin - 可能ですか?」という質問に対するこの回答で詳しく説明されているように、実行時にコンパイラを呼び出すことができます。

于 2010-07-18T06:21:05.373 に答える
8

これを行うことはできません (マニフェストを使用しても)。コードnew Object with Tには、 の組み合わせを表す新しい匿名クラスの作成が含まれObject with Tます。これをcreate関数に渡すには、実行時にこの新しいクラスを (新しいバイトコードで) 生成する必要がありますが、Scala には実行時に新しいクラスを生成する機能がありません。

1 つの戦略は、代わりにファクトリ メソッドの特別な機能をクラスのコンストラクターに転送してから、コンストラクターを直接使用することです。

別の考えられる戦略は、このクラスで使用することに関心のある特性への変換関数 (暗黙的またはその他) を作成することです。

于 2010-07-18T04:28:25.177 に答える