Vector

2013-11-03 36 views
16

için Eşleştirme "durum Nil" Bu Vector (veya Seq uygulayan herhangi bir koleksiyon) desen eşlemesinin nasıl kullanıldığıyla ilgili bu post okuduktan sonra, bu koleksiyonda desen eşleşmesini test ettim.Vector

object +: { 
    def unapply[T](s: Seq[T]) = 
    s.headOption.map(head => (head, s.tail)) 
} 

REPL bana gösteriyor ki

scala> Vector[Int]() == Nil 
res37: Boolean = true 

... o halde neden bir Vector için bu case Nil deyimi kullanamazsınız:

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") 
        ^

İşte +: açıklar dhg 'ın cevabı?

cevap

24

Karşılaştırma Vector[Int]() == Nil Karşılaştırma yapabilmeniz için tür düzeyinde herhangi bir kısıtlama olmadığı için; O, diğer taraftan, toplama şeklinden bağımsız eleman kıyasla bir öğe gerçekleştirmek için koleksiyonları için equals uygulanmasını sağlar:

desen eşleştirme olarak
Vector(1, 2, 3) == List(1, 2, 3) // true! 

, boş liste için bir durum var olamaz (Nil) tür listeyle ilgili değilse (bu bir Vector).

Bununla birlikte yapabilirsiniz:

val x = Vector(1, 2, 3) 

x match { 
    case y +: ys => println("head: " + y + "; tail: " + ys) 
    case IndexedSeq() => println("empty vector") 
} 

Ama x bir baş öğesi içermeyen çünkü eğer sadece burada varsayılan durumda kullanmak için öneririm, teknik olarak boş olmalıdır:

x match { 
    case y +: ys => println("head: " + y + "; tail: " + ys) 
    case _ => println("empty vector") 
} 
+0

Bu cevap için teşekkür ederiz. Tarafsız bir takip olarak, tipik olarak iyi veya kötü bir pratiğin örüntüsünde bir "yakalama" "_" kullanıyor mu? '' 'Kelimesini burada kullandığından beri, '' burada kullandığınız için nedeninizi anlıyorum '' Ama burada varsayılan durumu kullanmamı öneririm, çünkü eğer x'in bir baş elemanı yoksa, teknik olarak boş olmalıdır. ' –

+2

Yakalama, yanlışlıkla düşündüğünüzden daha fazla vaka yakalayabilir. Açıkça sayılan (kapalı) tipler için '_' kullanılmamasını tavsiye ederim. Örneğin, 'List' ile derleyici kontrolünüz var:' def foo (xs: Liste [Any]) = xs match {durum başı :: tail => "yes"} 'sizi uyarır, foo (xs: Vector [Any]) = xs match {durum başı +: kuyruk => "evet"} 'değil. 'List' için 'case Nil' kullanırım, endeksli seq 'case _' için ... –