我正在尝试使用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表达式中匹配类型匹配?
答案 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