unapply和unapplySeq有什么区别?

Dan*_*ton 37 scala pattern-matching unapply

为什么Scala有unapplyunapplySeq?两者有什么区别?我什么时候应该更喜欢一个?

huy*_*hjl 33

没有详细说明和简化:

对于常规参数apply构造和unapply解构:

object S {
  def apply(a: A):S = ... // makes a S from an A
  def unapply(s: S): Option[A] = ... // retrieve the A from the S
}
val s = S(a)
s match { case S(a) => a } 
Run Code Online (Sandbox Code Playgroud)

对于重复的参数,apply构造和unapplySeq解构:

object M {
  def apply(a: A*): M = ......... // makes a M from an As.
  def unapplySeq(m: M): Option[Seq[A]] = ... // retrieve the As from the M
}
val m = M(a1, a2, a3)
m match { case M(a1, a2, a3) => ... } 
m match { case M(a, as @ _*) => ... } 
Run Code Online (Sandbox Code Playgroud)

注意,在第二种情况下,重复参数像处理Seq和之间的相似性A*_*.

因此,如果您想要解构自然包含各种单个值的内容,请使用unapply.如果你想解构包含a的东西Seq,请使用unapplySeq.


Jul*_*ren 18

固定与可变的arity. Scala中的模式匹配(pdf)通过镜像示例很好地解释了它.我在这个答案中也有镜像示例.

简述:

object Sorted {
  def unapply(xs: Seq[Int]) =
    if (xs == xs.sortWith(_ < _)) Some(xs) else None
}

object SortedSeq {
  def unapplySeq(xs: Seq[Int]) =
    if (xs == xs.sortWith(_ < _)) Some(xs) else None
}

scala> List(1,2,3,4) match { case Sorted(xs) => xs }
res0: Seq[Int] = List(1, 2, 3, 4)
scala> List(1,2,3,4) match { case SortedSeq(a, b, c, d) => List(a, b, c, d) }
res1: List[Int] = List(1, 2, 3, 4)
scala> List(1) match { case SortedSeq(a) => a }
res2: Int = 1
Run Code Online (Sandbox Code Playgroud)

那么,您认为在以下示例中展示了哪些内容?

scala> List(1) match { case List(x) => x }
res3: Int = 1
Run Code Online (Sandbox Code Playgroud)