我试图了解List
s 在 Scala 中的实现。特别是,我试图弄清楚如何使用中缀运算符编写匹配表达式,例如:
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)
?
我试图了解List
s 在 Scala 中的实现。特别是,我试图弄清楚如何使用中缀运算符编写匹配表达式,例如:
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)
?
杰伊康拉德的回答几乎是正确的。重要的是,某处有一个名为的对象::
,它实现了该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]
在 and 的情况下::
,这个对象恰好来自一个扩展特征的案例类这一List
事实。但是,正如上面的示例所示,它根本不必是一个案例类。::
List
我相信:: 实际上是一个类(它是 List 的子类),所以说x :: xs
主要相当于List(x, xs)
.
您可以对具有运算符名称的其他案例类执行此操作。例如:
case class %%%(x: Int, y: Int)
a match {
case x %%% y => x + y
}
匹配表达式如何允许为 x :: xs 而不是 List(x, xs)?
要回答这个问题:
当被视为一种模式时,诸如p op q之类的中缀操作等价于op(p, q)。也就是说,中缀运算符 op 被视为 构造函数模式。
(Scala 编程,第 1 版,第 331 页)
另请参阅scala 案例类问题