2016-07-06 61 views

回答

4

我不知道为什么第二个编译,但我知道它不起作用!

scala> IndexedSeq(1,2, 3).toSeq match { 
    case a :: b :: c :: nil => println("toto"); 
} 
    |  | scala.MatchError: Vector(1, 2, 3) (of class scala.collection.immutable.Vector) 

如果你想匹配模式的序列,您可能需要使用+:作为联合运营商,或使用SEQ(A,B,C)如要匹配的模式。见this answer

以下作为一切工作的期望:

IndexedSeq(1,2, 3).toSeq match { 
    case Seq(a, b, c) => println("toto"); 
} 

IndexedSeq(1,2, 3) match { 
    case Seq(a, b, c) => println("toto"); 
} 

IndexedSeq(1,2, 3).toSeq match { 
    case a +: b +: c => println("toto"); 
} 

IndexedSeq(1,2, 3) match { 
    case a +: b +: c => println("toto"); 
} 
1

为了增加@ladams的答案。在IndexedSeq上调用toSeq只是指超级,因为后者从前者继承。在侧面说明,你也可以提取值的方式如下:

IndexedSeq(1, 2, 3) match { 
    case IndexedSeq(head, tail @ _*) => println("got match") 
    case _ => println("sth else") 
    } 

此外,SEQ仅仅是适当的返回集合的性状,例如

val s: Seq[Int] = 1 :: 2 :: 3 :: Nil 
s: Seq[Int] = List(1, 2, 3) 

因此,您可以将其与缺点匹配。而IndexedSeq返回一个Vector,它没有定义Cons操作符。

val s: IndexedSeq[Int] = IndexedSeq(1, 2, 3) 
s: IndexedSequence[Int] = Vector(1, 2, 3) 
+0

* Seq只是一个返回适当集合的特性*它是一个'trait'使它能够匹配'Cons'吗? 'IndexedSeq [A]'也是一个'特征'。 –

+0

调用Seq(1,2,3)返回实现Cons的List(1,2,3)并不是它的特性,而是事实。 – sebszyller

+0

但是'IndexedSeq(1,2,3).toSeq'返回一个'Vector [Int]'。 –

1

第一个例子并不编译,因为图案a :: b :: c的类型是List[something]和选择IndexedSeq(1, 2, 3)的类型是IndexedSeq[Int]。因为List不是IndexedSeq的子类型,所以编译器知道匹配不可能成功并产生错误。如the language specification(稍微修改以删除公式)中所述:

每种模式都可以用两种方式键入。首先,试图将选择器的类型作为其预期类型来输入模式。如果失败,则改为使用修改后的预期类型进行输入,该修改后的预期类型是由undefined替换每次出现的类型参数后得到的。如果第二步也失败,则会导致编译时错误。

在第二种情况下,选择的类型是Seq[Int],所以只要编译器而言,它可能变成是一个List[Int]在运行时,在这种情况下,它会成功。它可能会发出警告,说明匹配可能会失败(事实上它的确如此),但Scala设计者另有决定:只有当选择器的类型为sealed时才会发出此警告。