Dlaczego Scala ma zarówno unapply
, jak i unapplySeq
? Jaka jest różnica między tymi dwoma? Kiedy powinienem preferować jeden nad drugim?Jaka jest różnica między unapply i unapplySeq?
33
A
Odpowiedz
26
Nie wdając się w szczegóły i upraszczając trochę:
Dla stałych parametrów apply
buduje i unapply
de-struktur:
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 }
przypadku wielokrotnego parametrów apply
buduje i unapplySeq
de-struktur:
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 @ _*) => ... }
Należy zauważyć, że w tym drugim przypadku powtarzające się parametry są traktowane jak Seq
i podobieństwo między A*
i _*
.
Więc jeśli chcesz zdekantować coś, co naturalnie zawiera różne pojedyncze wartości, użyj unapply
. Jeśli chcesz zdeformować coś zawierającego Seq
, użyj unapplySeq
.
18
Fixed-arity vs. variable arity. Pattern Matching in Scala (pdf) wyjaśnia to dobrze, z przykładami dublowania. Mam również przykłady dublowania w this answer.
skrócie:
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
Więc, co myślisz jest eksponowana w poniższym przykładzie?
scala> List(1) match { case List(x) => x }
res3: Int = 1
Powiązane problemy
- 1. Jaka jest różnica między? : i ||
- 2. Jaka jest różnica między $ i $$?
- 3. Jaka jest różnica między Subtotal i BaseSubtotal?
- 4. Jaka jest różnica między DetachedCriteria i ICriteria
- 5. Jaka jest różnica między & # x00A0; i ?
- 6. Jaka jest różnica między lex i yacc
- 7. jaka jest różnica między dijit i dojo
- 8. Jaka jest różnica między Control.Select() i Control.Focus()?
- 9. Jaka jest różnica między System.Windows.Controls.Control i System.Windows.Forms.Control?
- 10. Jaka jest różnica między apletami i SWING?
- 11. Jaka jest różnica między session.commit() i session.flush()?
- 12. Jaka jest różnica między ImageView.setBackgroundResource i ImageView.setImageResource?
- 13. Jaka jest różnica między Konwertuj i parsuj?
- 14. Jaka jest różnica między JSP i JSTL?
- 15. Jaka jest różnica między Lazarus i CodeTyphon
- 16. Jaka jest różnica między crc32 i crc32b?
- 17. Jaka jest różnica między TypedArray.getInteger() i TypedArray.getInt()?
- 18. jaka jest różnica między ARM7 i ARM7s
- 19. Jaka jest różnica między http_build_str() i http_build_query()?
- 20. Jaka jest różnica między "CompletionStage" i "CompletableFuture"?
- 21. Jaka jest różnica między mock.patch.object (... i mock.patch (
- 22. Jaka jest różnica między GetBlobReference i GetBlobReferenceFromServer?
- 23. Jaka jest różnica między NSLayoutAttributeBaseline i NSLayoutAttributeBottom?
- 24. Jaka jest różnica między handlebar.js i handlebar.runtime.js?
- 25. Jaka jest różnica między innerText i outerText?
- 26. Jaka jest różnica między Json i Jsonp?
- 27. Jaka jest różnica między WCF i WPF?
- 28. Jaka jest różnica między runghc i runhaskell?
- 29. Jaka jest różnica między -hivevar i -hiveconf?
- 30. Jaka jest różnica między writeUTF i writeChars?
Ah dzięki! To ma sens. Wychodząc z perspektywy Haskella, myślę o dopasowaniu na "Liście (a, b, c)" jako pomijaniu w dopasowaniu na 'a :: b :: c :: Nil', ale wygląda na to, że Scala tego nie robi; zamiast tego używa metody 'unapplySeq'' List'. –
Referat, o którym mowa w tej odpowiedzi, można znaleźć tutaj: http://www.michaelrueegg.name/static/papers/PatternMatchingInScala.pdf –
@dan Scala można dopasować na listach w sposób zgodny z oczekiwaniami, stosując metodę unapply w: : obiekt towarzyszący. Zgodnie z oczekiwaniami, to unapply po prostu niszczy List (lub raczej: :) w głowę i ogon. Zauważ, że działa to tylko dla list, a nie dla żadnego seq. –