1

假设我有一个带有类型参数的类和一个方法,该方法仅在使用具有表示类型的特定特征参数化该类时才应返回实例的副本。我可以很容易地做到这一点。我不能做的是给该方法一个合理的返回类型:

case class Foo[+A](a: A) {
  // Compiles
  def gotFooBar(implicit evidence: A <:< Bar[_]) = copy(a = a.Copy())

  // Does not compile
  def gotFooBar(implicit evidence: A <:< Bar[_]): Foo[A] = copy(a = a.Copy())
}

trait Bar[+B <: Bar[B]] {
  def Copy(): B // Return underlying type
}

case class Grill() extends Bar[Grill] {
  def Copy() = Grill()
}

该函数的返回类型是什么,或者更重要的是,我将如何设置类型以使其成为返回类型?有人还可以指出真正的返回类型如何可能是 的超类型Foo[A]

4

2 回答 2

2

好吧,因为你只需要Bar[_]你 getAny作为调用的结果a.Copy。您需要该gotFooBar方法的类型参数:

case class Foo[+A](a: A) {
   def gotFooBar[B <: Bar[B]](implicit evidence: A <:< B): Foo[B] = {
      val bar = a: B
      copy(a = bar.Copy())
   }
}

第二个问题是,如何强制它Foo[B]Foo[A]. 您只需要添加A作为下限B

def gotFooBar[B >: A <: Bar[B]](implicit evidence: A <:< B): Foo[B]
于 2012-07-21T00:32:43.390 回答
0

这是@0__ 对答案的后续回答。A如果有与之关联的 Manifest ,情况会变得更加复杂:

case class Foo[+A : Manifest](a: A)

方法类型参数B也需要 Manifest(即使您不使用它)。添加 Manifest ( ) 的常用方法也不起作用,因为当方法还具有隐式参数(在本例中为 ): Manifest时,这是不允许的。implicit evidence清单可以放在隐式参数列表中,如下所示:

def gotFooBar[B >: A <: Bar[B]]
  (implicit m: Manifest[B], evidence: A <:< B): Foo[B] =
  copy(a = a.Copy())
于 2012-07-22T16:31:08.730 回答