中缀运算符上的Scala匹配分解
-
06-07-2019 - |
题
我正在尝试理解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)
?
解决方案
杰伊康拉德的答案几乎是正确的。重要的是某处有一个名为
::
的对象,它实现 unapply
方法,返回类型 Option [(A,列表[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
特征。但是,如上例所示, 根本不是。
其他提示
我相信 ::实际上是一个类(它是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)。也就是中缀 operator op被视为a 构造函数模式。
(Scala编程,第1版,第331页)
另请参阅 scala案例类问题
不隶属于 StackOverflow