2016-07-25 12 views
2

から具象クラスをインスタンス化Scalaは私がジェネリックであり、このように書き形質を持つジェネリック型

object MyTraitFactory { 
    def apply[T](param1: Boolean, param2: Boolean): MyTrait[T] = { 
    // based on the type of T, I would like to instantiate sub types 
    } 
} 

Iたとえば、次のような具体的な実装が行われています。

class MyStringTrait extends MyTrait[String] 

class MyIntTrait extends MyTrait[Int] 

これで、オブジェクトファクトリに入力し、対応する実装をインスタンス化します。助言がありますか?

答えて

3

これは、暗黙のtypeclassを使用してスカラで解決できます。あなたのタイプごとに具体的な実装と工場出荷時の形質を作成します。

object MyTraitFactory { 

    def apply[T](param1: Boolean, param2: Boolean)(implicit factory: MyTraitCreator[T]): MyTrait[T] = { 
    // call the typeclass create method 
    factory.create(param1, param2) 
    } 

    // factory trait 
    trait MyTraitCreator[T] { 
    def create(param1: Boolean, param2: Boolean): MyTrait[T] 
    } 

    // provide an implicit factory object for the specific types: 
    object MyTraitCreator { 

    implicit object MyStringTraitCreator extends MyTraitCreator[String] { 
     override def create(param1: Boolean, param2: Boolean): MyTrait[String] = { 
     // create the String type here 
     new MyStringTrait 
     } 
    } 

    implicit object MyIntTraitCreator extends MyTraitCreator[Int] { 
     override def create(param1: Boolean, param2: Boolean): MyTrait[Int] = { 
     // create the Int type here 
     new MyIntTrait 
     } 
    } 
    } 
} 

Scalaの暗黙のパラメータを使用して、型クラスを「隠します」。しかし、これが機能するには、暗黙のファクトリオブジェクトをコンパイラがimplicits(例えば、上記のようなコンパニオンオブジェクトMyTraitCreator)を探す場所に保つ必要があります。パターンはimplicitがなければ同様に機能しますが、各呼び出しで具体的なファクトリを提供するために呼び出し元が必要です。

このソリューションには多くのボイラープレートコードが含まれていますが、コンパイル時には静的に動作し、タイプ消去されません。それはscalaの構文的な砂糖が付属する:

def apply[T: MyTraitCreator](param1: Boolean, param2: Boolean): MyTrait[T] = { 
    // call the typeclass create method 
    implicitly[MyTraitCreator[T]].factory.create(param1, param2) 
} 
関連する問題