Scala - 匹配选项元组

Kar*_*ten 5 scala pattern-matching option

我有:

val foo = Some(List(1, 2, 3)) -> Some("y")
Run Code Online (Sandbox Code Playgroud)

我想投射它:

foo match {
    case (Some(x), Some(y)) => println(x + " " + y)
    case _ => println("error")
Run Code Online (Sandbox Code Playgroud)

这适用于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 ...
Run Code Online (Sandbox Code Playgroud)

这是为什么?

当然我可以使用,getOrElse()但看起来不那么优雅.

很多,卡斯滕

更新:

foo match {
 case (x: Some[List[Int]], y: Some[Int]) => println(x.get)
 case _ => println("error")
}
Run Code Online (Sandbox Code Playgroud)

失败也是:

error: pattern type is incompatible with expected type;
 found   : Some[Int]
 required: None.type
Run Code Online (Sandbox Code Playgroud)

我认为case _会照顾到这一点.

Rüd*_*ehn 6

编译器会告诉你一些事情.如果你有一个表达式

val foo = Some(List(1, 2, 3)) -> None
Run Code Online (Sandbox Code Playgroud)

它将具有类型(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)
Run Code Online (Sandbox Code Playgroud)

因此,您在编译时知道元组的第二个元素只能是None,与Some的匹配永远不会成功.因此错误消息.

如果你给foo一个限制较少的类型它会起作用.

val foo : (Option[List[Int]], Option[String]) = Some(List(1, 2, 3) -> None
Run Code Online (Sandbox Code Playgroud)

请注意,这完全是应该的.匹配一些永远不会发生的事情几乎肯定是一个错误.您必须向上转换为任何以避免编译时错误(但随后您将收到运行时错误.