3

私が持っているとしましょう:

trait A

class B extends A

class C extends A

次のようなタイプ パラメータを設定する方法はありますか。

class Foo[AType <: A with canCreateInstance]
    def newAType : AType = new AType

Foo は、B や C などの A を実装するクラスのみを取得でき、A 自体は取得できないという考えです。

4

2 に答える 2

0

特性にコンパニオン オブジェクトを与えてみてください。コンパニオン オブジェクトは、 のインスタンスを返すオブジェクトになりますAType

コンパニオン オブジェクトを使用する場合:

trait Queue[T]{
    def head:T
    def tail:Queue[T]
    def enqueue(x:T):Queue[T]
}

object Queue{
    def apply[T](xs: T*): Queue[T] = 
        new QueueImpl[T](xs.toList)

    private class QueueImpl[T](
        private val leading:List[T],
        private val trailing:List[T]=Nil
    ) extends Queue[T]
    {
       // methods in here
    }
}

多分これはもっと簡単です:

object A{

  def aType(...):A = new B(...)

  def aType(...):A = new C(...)


  /* classes */

  private class C(...) extends A

  private class B(...) extends A{
    // blah blah
  }

}
于 2013-02-22T16:58:53.670 に答える
0

特定のタイプのインスタンスを作成する最も一般的な方法は、コメントで言及されている @bluenote10 のようにファクトリ スタイルを使用することです。

そのために、最初にファクトリ定義を作成します

// factory definition
trait CanCreateInstance[T] {
  def create: T
}

次に、私たちのクラスでは、その特定のタイプのファクトリを要求します

class Foo[T <: A](implicit factory: CanCreateInstance[T]) {
  def newT: T = factory.create
}

のコンパニオン オブジェクトにいくつかのデフォルト ファクトリを追加できます。CanCreateInstance

object CanCreateInstance {
  // define default availble instance creators
  implicit def bFactory = new CanCreateInstance[B] {
    def create = new B
  }
}

次に、このように簡単に使用できます

val fooB = new Foo[B]
val newB = fooB.newT

Foo別の型のインスタンスを作成できるようにする必要がある場合は、単純にファクトリを提供できます。

implicit val cFactory = new CanCreateInstance[C] {
  def create = new C
}

val fooC = new Foo[C]
val newC = fooC.newT

Fooこの構成により、デフォルトのファクトリが利用できない場合、任意のユーザーがファクトリを提供できます。たとえば、工場を提供することもできAます

implicit val aFactory = new CanCreateInstance[A] {
  def create = new A {}
}

ファクトリを作成せずに実行時に不明なタイプからインスタンスを作成する必要がある場合は、TypeTag. これに関する情報は、Scala: What is a TypeTag and how do I use it? にあります。

于 2013-02-23T12:56:30.160 に答える