可以使用隐式类型类在scala中解决这个问题。创建一个工厂特质,并为每种类型创建具体的实现:
object MyTraitFactory {
def apply[T](param1: Boolean, param2: Boolean)(implicit factory: MyTraitCreator[T]): MyTrait[T] = {
factory.create(param1, param2)
}
trait MyTraitCreator[T] {
def create(param1: Boolean, param2: Boolean): MyTrait[T]
}
object MyTraitCreator {
implicit object MyStringTraitCreator extends MyTraitCreator[String] {
override def create(param1: Boolean, param2: Boolean): MyTrait[String] = {
new MyStringTrait
}
}
implicit object MyIntTraitCreator extends MyTraitCreator[Int] {
override def create(param1: Boolean, param2: Boolean): MyTrait[Int] = {
new MyIntTrait
}
}
}
}
Scala通过隐式参数来“隐藏”类型类。但为了使其工作,您必须确保将隐式工厂对象放在编译器寻找隐式的位置(例如上面的
MyTraitCreator
的伴生对象)。该模式即使没有
implicit
也能很好地工作,但然后需要调用者在每次调用时提供具体工厂。
该解决方案包括大量样板代码,但在编译时静态工作,并且不会受到类型擦除的影响。Scala甚至带有语法糖:
def apply[T: MyTraitCreator](param1: Boolean, param2: Boolean): MyTrait[T] = {
implicitly[MyTraitCreator[T]].factory.create(param1, param2)
}