unapply 和 unapplySeq 有什么区别?

发布于 2024-12-18 05:23:15 字数 98 浏览 1 评论 0原文

为什么 Scala 同时具有 unapplyunapplySeq ?两者有什么区别?我什么时候应该选择其中一种而不是另一种?

Why does Scala have both unapply and unapplySeq? What is the difference between the two? When should I prefer one over the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

往日情怀 2024-12-25 05:23:15

不深入细节并稍微简化一下:

对于常规参数 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 } 

对于重复参数,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 @ _*) => ... } 

请注意,在第二种情况下,重复的参数被视为 Seq 以及 A*_* 之间的相似性

因此,如果您想对自然包含各种单个值的内容进行解构,请使用 unapply。如果您想对包含 Seq 的内容进行解构,请使用 unapplySeq

Without going into details and simplifying a bit:

For regular parameters apply constructs and unapply de-structures:

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 } 

For repeated parameters, apply constructs and unapplySeq de-structures:

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 @ _*) => ... } 

Note that in that second case, repeated parameters are treated like a Seq and the similarity between A* and _*.

So if you want to de-structure something that naturally contains various single values, use unapply. If you want to de-structure something that contains a Seq, use unapplySeq.

书信已泛黄 2024-12-25 05:23:15

固定数量与可变数量。 Scala 中的模式匹配 (pdf)< /a> 通过镜像示例很好地解释了这一点。我在这个答案中也有镜像示例。

简言之:

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

那么,您认为下面的例子体现了哪一点?

scala> List(1) match { case List(x) => x }
res3: Int = 1

Fixed-arity vs. variable arity. Pattern Matching in Scala (pdf) explains it well, with mirroring examples. I also have mirroring examples in this answer.

Briefly:

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

So, which do you think is exhibited in the following example?

scala> List(1) match { case List(x) => x }
res3: Int = 1
我三岁 2024-12-25 05:23:15

一些例子:

scala> val fruit = List("apples", "oranges", "pears")
fruit: List[String] = List(apples, oranges, pears)

scala> val List(a, b, c) = fruit
a: String = apples
b: String = oranges
c: String = pears

scala> val List(a, b, _*) = fruit
a: String = apples
b: String = oranges

scala> val List(a, _*) = fruit
a: String = apples

scala> val List(a,rest @ _*) = fruit
a: String = apples
rest: Seq[String] = List(oranges, pears)

scala> val a::b::c::Nil = fruit
a: String = apples
b: String = oranges
c: String = pears

scala> val a::b::rest = fruit
a: String = apples
b: String = oranges
rest: List[String] = List(pears)

scala> val a::rest = fruit
a: String = apples
rest: List[String] = List(oranges, pears)

Some examples:

scala> val fruit = List("apples", "oranges", "pears")
fruit: List[String] = List(apples, oranges, pears)

scala> val List(a, b, c) = fruit
a: String = apples
b: String = oranges
c: String = pears

scala> val List(a, b, _*) = fruit
a: String = apples
b: String = oranges

scala> val List(a, _*) = fruit
a: String = apples

scala> val List(a,rest @ _*) = fruit
a: String = apples
rest: Seq[String] = List(oranges, pears)

scala> val a::b::c::Nil = fruit
a: String = apples
b: String = oranges
c: String = pears

scala> val a::b::rest = fruit
a: String = apples
b: String = oranges
rest: List[String] = List(pears)

scala> val a::rest = fruit
a: String = apples
rest: List[String] = List(oranges, pears)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文