Dopo aver letto questo post su come utilizzare la corrispondenza del modello su Vector
(o qualsiasi raccolta che implementa Seq
), ho verificato la corrispondenza del modello su questa raccolta.Pattern Matching "case Nil" per Vector
scala> x // Vector
res38: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> x match {
| case y +: ys => println("y: " + "ys: " + ys)
| case Nil => println("empty vector")
| }
<console>:12: error: pattern type is incompatible with expected type;
found : scala.collection.immutable.Nil.type
required: scala.collection.immutable.Vector[Int]
Note: if you intended to match against the class, try `case _: <none>`
case Nil => println("empty vector")
^
Ecco dhg
's risposta che spiega +:
:
object +: {
def unapply[T](s: Seq[T]) =
s.headOption.map(head => (head, s.tail))
}
REPL
mi dimostra che
scala> Vector[Int]() == Nil
res37: Boolean = true
... e allora perché non posso usare questa case Nil
economico per un Vector
?
Grazie per questa risposta. Come follow-up a parte, l'uso di un "catch-all" '_' nell'abbinamento di modelli è in genere una buona o cattiva pratica? Capisco la tua ragione per usare '_' qui da quando, nelle tue parole," Ma ti suggerirei di usare solo il caso predefinito qui, perché se x non ha un elemento head, deve essere tecnicamente vuoto. " –
Catch all può catturare accidentalmente più casi di quanto pensassi. Per i tipi chiaramente elencati (sigillati) suggerirei di non usare '_'. Ad esempio, con 'List' hai il controllo del compilatore:' def foo (xs: List [Any]) = xs match {case head :: tail => "yes"} 'ti dà un avvertimento,' def foo (xs: Vector [Any]) = xs match {case head +: tail => "yes"} 'no. Per 'List' vorrei usare' case Nil', per seq 'caso indicizzato _' ... –