我有:
val foo = Some(List(1, 2, 3)) -> Some("y")
我想将其匹配:
foo match {
case (Some(x), Some(y)) => println(x + " " + y)
case _ => println("error")
这适用于Some(List(1, 2, 3) -> Some("score"))
,但Some(List(1, 2, 3) -> None
,None -> Some("y")
或None -> None
无效:
error: constructor cannot be instantiated to expected type;
found : Some[A]
required: None.type
error: not found: value ...
为什么?
当然我可以使用getOrElse()
,但这看起来并不那么优雅。
很多, 卡斯滕
更新
foo match {
case (x: Some[List[Int]], y: Some[Int]) => println(x.get)
case _ => println("error")
}
也失败了:
error: pattern type is incompatible with expected type;
found : Some[Int]
required: None.type
我认为case _
会照顾到这一点。
答案 0 :(得分:6)
编译器会告诉你一些事情。如果你有一个像
这样的表达式val foo = Some(List(1, 2, 3)) -> None
它将具有类型(Some [List [Int]],None.type),您可以通过在scala控制台中键入表达式轻松看到
scala> val foo = Some(List(1, 2, 3)) -> None
foo: (Some[List[Int]], None.type) = (Some(List(1, 2, 3)),None)
所以你知道在编译时元组的第二个元素只能是None,与some的匹配永远不会成功。因此错误信息。
如果你给foo一个限制较少的类型它会起作用。
val foo : (Option[List[Int]], Option[String]) = Some(List(1, 2, 3) -> None
请注意,这完全是应该的。匹配一些永远不会发生的事情几乎肯定是一个错误。您必须向上转换为任何以避免编译时错误(但随后您将收到运行时错误。
答案 1 :(得分:2)
在下面的代码中,Scala会在foo match
上收到编译错误,但会使用foo2
/ foo3
进行编译并正确运行:
val foo = None -> None
val foo2: (Option[Any], Option[Any]) = None -> None
val foo3: (Option[Any], Option[Any]) = foo
foo match {
case (Some(x), Some(y)) => println(x + " " + y)
case _ => println("error")
}