3

在下面的例子中,Scala 不能使用提取器,这让我发疯:

trait Sys[S <: Sys[S]]

object Element {
  object Foo {
    def unapply[S <: Sys[S]](foo: Foo[S]): Option[Any] = ???
  }
  trait Foo[S <: Sys[S]] extends Element[S]
}
trait Element[S <: Sys[S]]

这是一个测试用例:

def test[S <: Sys[S]](elem: Element[S]) = elem match {
  case Element.Foo(_) => ???
  case _ => ???
}

失败了

inferred type arguments [S] do not conform to method unapply's type parameter
  bounds [S <: Sys[S]]

(在 Scala 2.9.2 和 2.10 中)。


如果我删除 F-bound 它可以工作:

trait Sys

object Element {
  object Foo {
    def unapply[S <: Sys](foo: Foo[S]): Option[Any] = ???
  }
  trait Foo[S <: Sys] extends Element[S]
}
trait Element[S <: Sys]

def test[S <: Sys](elem: Element[S]) = elem match {
  case Element.Foo(_) => ???
  case _ => ???
}

我想这是那些“讨厌 Scala 的日子”之一。这可以这么傻吗?基本上它和这个问题一样,没有正确的答案。

谢谢。

4

1 回答 1

-1

当尝试test使用null参数和Sys[Any]类型参数调用 a 时,它确实表示:

type arguments [Sys[Any]] do not conform to trait Element's type parameter 
  bounds [S <: Sys[S]]

尝试方差:

trait Sys[-S]

object Element {
  object Foo {
    def unapply[S <: Sys[S]](foo: Foo[S]): Option[Any] = ???
  }
  trait Foo[S <: Sys[S]] extends Element[S]
}
trait Element[S <: Sys[S]]

def test[S <: Sys[S]](elem: Element[S]) = elem match {
  case f: Element.Foo[S] => "ok"
  case _ => "smth else"
}

// test
test(new Element.Foo[Sys[Any]](){})  // "smth else"
test(new Element[Sys[Any]](){})      // "ok"
于 2013-02-03T16:53:53.867 回答