具体做法是:
scala> def f(n: Seq[Any]) = n match {
case Nil => "Empty"
case h :: t => "Non-empty"
}
f: (n: Seq[Any])String
scala> f(Stream())
res1: String = Empty
scala> f(List(1))
res17: String = Non-empty
scala> f(Stream(1))
scala.MatchError: Stream(1, ?) (of class scala.collection.immutable.Stream$Cons)
at .f(<console>:13)
... 33 elided
还有很多其他方法可以实现这一点,但在编写代码时,代码是静态安全的,并且在运行时失败。发生了什么事?
答案 0 :(得分:2)
对于Stream
, concat 符号应为#::
,模式匹配应为:
def f(n: Seq[Any]) = n match {
case Nil => "Empty"
case h :: t => "Non-empty"
case h #:: t => "Non-empty stream"
}
::
的适用于List
/ Seq
类型(List
扩展自Seq
:),请参阅:
final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
答案 1 :(得分:1)
您只能使用::
来解构List
而不是Stream
。由于您提供的Stream
与List
不匹配,因此您获得了MatchError
。如果您希望f
使用该类型的匹配(提取器)来支持流,则可以使用#::
。
def f(n: Seq[Any]) = n match {
case Nil => "Empty"
case h :: t => "Non-empty"
case h #:: t => "Non-empty"
}
一般来说,这种方法非常脆弱,因为上面显示的两种提取器类型只适用于这两种类型的Seq
。其他人可能会休息如果您关心的是确定Seq
是否为空,那么只需使用n.nonEmpty
或n.isEmpty
并处理Boolean
结果即可。否则,尝试在未密封的特征上提供详尽的匹配肯定会失败。
您还可以使用Seq
提取器:
def f(n: Seq[Any]) = n match {
case Nil => "Empty"
case Seq(_*) => "Non-empty"
}
答案 2 :(得分:0)
虽然其他答案正确显示了Stream
特定的提取程序#::
,但Seq
存在一个提取程序(以及从SeqLike
派生的任何内容) - 它是+:
,这适用于List
(作为::
)和Stream
(作为`#::)。使用此提取器,您可以轻松编写适用于以下两者的函数:
def f(n: Seq[Any]) = n match {
case h +: t => "Non-empty"
case _ => "Empty"
}