斯卡拉实例化一个具体的类从泛型类型

问题描述:

我有一个特点是通用的,是这样的:斯卡拉实例化一个具体的类从泛型类型

trait MyTrait[T] { 
    def doSomething(elems: Seq[T]) 
} 

然后我有一个对象的工厂,其定义是这样的:

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

我有具体的实施,例如:

class MyStringTrait extends MyTrait[String] 

class MyIntTrait extends MyTrait[Int] 

我现在需要那个神奇的位,会寻找键入我的对象工厂并实例化相应的实现。有什么建议么?

这可以使用隐式类型类在scala中解决。创建具体实现的工厂的特质对每个类型:

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 
     } 
    } 
    } 
} 

斯卡拉“隐藏”使用隐含参数的类型类。但是为了达到这个目的,你必须确保将隐式工厂对象保留在编译器寻找隐含位置的地方(例如,如上所述的伴随对象为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) 
}