是否可以在Scala表达式中匹配类型匹配?

时间:2015-11-06 21:51:15

标签: scala pattern-matching for-comprehension

我正在尝试使用for表达式映射选项,但我只想匹配选项的内容属于特定类型。我认为可行的是:

for {
  vcs: Mercurial <- maybeVcs
} yield vcs

但是会产生以下编译错误:

<console>:76: error: type mismatch;
 found   : sbtrelease.Mercurial => sbtrelease.Mercurial
 required: sbtrelease.Vcs => ?
                vcs: Mercurial <- get (releaseVcs in Compile)
                               ^

是否可以在for表达式中匹配类型匹配?

3 个答案:

答案 0 :(得分:2)

如果您使用for代替trait A case class B(x: Int) extends A case class C(y: Int) extends A val someB: Option[A] = Some(B(2)) val someC: Option[A] = Some(C(2)) val noneA: Option[A] = None someB.collect { case n: B => n } // Some(B(2)) someC.collect { case n: B => n } // None noneA.collect { case n: B => n } // None ,那真的很简单:

var theRightSide = document.getElementById("rightSide");

答案 1 :(得分:1)

这种模式匹配不起作用的事实实际上是一个错误(至少它不符合规范)。请参阅https://issues.scala-lang.org/browse/SI-900

但是,有一个简单的解决方法。 在某处定义以下对象:

object Id { unapply[T](x:T) = Some(x) }

现在,您可以使用Id(x)作为匹配所有内容的模式匹配,并将x绑定到匹配的任何内容。所以基本上是一个毫无意义的构造,因为Id(pattern)pattern相同。

但是,它有一个作用:Id(...)中的类型注释不会被解释为类型注释,而是作为类型模式。因此

for {
  Id(vcs: Mercurial) <- maybeVcs
} yield vcs

会产生你想要的效果。 (与Bob's answer不同,整体表达式的类型为Seq[Mercurial],而不是Seq[Vcs]。)

答案 2 :(得分:0)

您可以使用丑陋的测试:

for {
  vcs <- maybeVcs
  if vcs.instanceof[Mercurial]
} yield vcs