2011-12-29 60 views
7

鉴于这种模式匹配:斯卡拉匹配的情况下使用::对列表

List(1,2,3) match { 
    case head :: tail => println(">>> head=" + head) 
} 

我假设“::”是scala.collection.immutable发现的情况下类,但怎么是“:: '允许用这种形式写(中缀记法)? - 是否有一个特定的规则允许这样做?

感谢

+2

您可能想查看[中缀运算符上的Scala匹配分解](http://stackoverflow.com/questions/1022218/scala-match-decomposition-on-infix-operator)和[这个案例如何匹配p attern working?](http://stackoverflow.com/questions/1059145/how-is-this-case-class-match-pattern-working) – 4e6 2011-12-29 08:55:12

回答

25

,你甚至可以写:

val head :: tail = List(1, 2, 3) 

基本上任何其中模式预期(赋值,一个match陈述或线在换理解)可以采取提取,这是定义为具有unapply方法的实体。

其中一块句法糖 scala为您提供的是;如果你有一个提取器X(a, b),这可以写为a X b。下面是与case类(其中有一个默认的提取器)的例子:

scala> case class X(a: Int, b: String) 
defined class X 

scala> val a X b = X(1, "two") 
a: Int = 1 
b: String = two 

写这样的实体延伸到类型以及能力:

scala> type MappedTo[A, B] = Map[A, B] 
defined type alias MappedTo 

scala> def foo(m: Int MappedTo String) = m foreach println 
foo: (m: MappedTo[Int,String])Unit 

注意,在两种情况下,不scala将这些中缀运算符限制为符号标识符

2

斯卡拉实际上有一个不可变类::它代表了非空列表(补到Nil)。有一个中级的符号(这也是如何工作的A <:< B),它允许你写head :: tail而不是::(head, tail)。由于::是一个案例类,因此它有一个默认的unapply,这使得case可以像您说明的那样工作。