中缀运算符上的Scala匹配分解

时间:2009-06-20 18:45:05

标签: list scala match infix-operator

我正在尝试了解Scala中List的实现。特别是我试图了解如何使用中缀运算符编写匹配表达式,例如:

a match {
  case Nil => "An empty list"
  case x :: Nil => "A list without a tail"
  case x :: xs => "A list with a tail"
}

如何将匹配表达式设为x :: xs而不是List(x, xs)

3 个答案:

答案 0 :(得分:13)

杰伊康拉德的答案几乎是正确的。重要的是某处有一个名为::的对象实现unapply方法,返回类型Option[(A, List[A])]。正是如此:

object :: {
  def unapply[A](ls: List[A]): Option[(A, A)] = {
    if (ls.empty) None
    else Some((ls.head, ls.tail))
  }
}

// case objects get unapply for free
case object Nil extends List[Nothing]

对于::List,此对象恰好是::是扩展List特征的案例类的事实。但是,如上例所示, 根本不是。

答案 1 :(得分:7)

我相信:: is actually a class(这是List的子类),所以说x :: xs大部分等同于List(x, xs)

您可以使用具有运算符名称的其他案例类执行此操作。例如:

case class %%%(x: Int, y: Int)

a match {
  case x %%% y => x + y
}

答案 2 :(得分:2)

  

匹配表达式如何允许为x :: xs而不是List(x,xs)?

回答这个问题:

  

当被视为模式时,是一个中缀    p op q 等操作是等效的   到 op(p,q)。也就是中缀   operator op被视为a   构造函数模式

(Scala编程,第1版,第331页)

另见scala case classes questions