Scala工厂使用apply方法的泛型类型?

假设我有以下特征来定义一个接口并采用几个类型参数……

trait Foo[A,B] {

    // implementation details not important

}

我想使用伴侣对象作为特征的具体实现的工厂.我还想强制用户使用Foo接口而不是子类化所以我隐藏了伴随对象中的具体实现,如下所示:

object Foo {

  def apply[A,B](thing: Thing): Foo[A,B] = {
    ???
  }

  private case class FooImpl[A1,B1](thing: Thing) extends Foo[A1,B1]

  private case class AnotherFooImpl[A2,B1](thing: Thing) extends Foo[A2,B1]

}

我希望能够按如下方式使用工厂:

val foo = Foo[A1,B1](thing)  // should be an instance of FooImpl

val anotherFoo = Foo[A2,B1](thing)  // should be an instance of AnotherFooImpl

如何实现apply方法来实现这一目标?这SO post似乎接近标志.

解决方法

怎么样:

trait Foo[A,B]
trait Factory[A,B] {
  def make(thing: Thing): Foo[A,B]
}

class Thing

object Foo {
def apply[A,B](thing: Thing)(implicit ev: Factory[A,B]) = ev.make(thing)

private case class FooImpl[A,B](thing: Thing) extends Foo[A,B]
private case class AnotherFooImpl[A,B]

implicit val fooImplFactory: Factory[Int,String] = new Factory[Int,String] {
  override def make(thing: Thing): Foo[Int,String] = new FooImpl[Int,String](thing)
}

implicit val anotherFooImplFactory: Factory[String,String] = new Factory[String,String] {
  override def make(thing: Thing): Foo[String,String] = new AnotherFooImpl[String,String](thing)
}

现在:

def main(args: Array[String]): Unit = {
  import Foo._

  val fooImpl = Foo[Int,String](new Thing)
  val anotherFooImpl = Foo[String,String](new Thing)

  println(fooImpl)
  println(anotherFooImpl)
}

产量:

FooImpl(testing.X$Thing@4678c730)
AnotherFooImpl(testing.X$Thing@c038203)

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...