Dan*_*wak 22
链表由两种情况组成:cons单元(具有头部和尾部)和空列表.这些情况被称为::
和Nil
Scala中分别作为与ML遗产其他语言.在不可变的实现中,最自然的编码看起来像这样:
sealed trait List[+A]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
case object Nil extends List[Nothing]
Run Code Online (Sandbox Code Playgroud)
这很好用,它确实没什么问题.您可以::
在List
(或者prepend
,如果您愿意)定义方法,并且事情完全按照您的预期工作.在这种情况下,"具体实现" List
将是Cons
技术上的两个Cons
并且Nil
是具体实现.
这是问题所在:我们希望能够在一个实例上进行模式匹配List
以获取内容.事实上,该模式匹配需要以下语法:
def sum(xs: List[Int]): Int = xs match {
case Cons(hd, tl) => hd + sum(tl)
case Nil => 0
}
Run Code Online (Sandbox Code Playgroud)
虽然这有点难看.我们真正想要的是能够::
在我们的模式匹配中使用运算符,就像我们在最初构造列表时使用它一样.这就是这个Cons
班级的名字::
.
通过定义两个参数的case类,我们基本上告诉Scala我们希望它允许我们在模式匹配中使用该case类作为中缀提取器.尾部冒号使该提取器成为右关联,为我们提供了预期的语法:
sealed trait List[+A]
case class ::[+A](head: A, tail: List[A]) extends List[A]
case object Nil extends List[Nothing]
def sum(xs: List[Int]): Int = xs match {
case hd :: tl => hd + sum(tl)
case Nil => 0
}
Run Code Online (Sandbox Code Playgroud)
这就是为什么任何List
具有内容的实例将是类的实例::
,因为这是非空的实现List
.
huy*_*hjl 21
这适用于模式匹配.你有一个叫做中缀运算符模式的东西,其中模式p op q
等同于构造函数或提取器模式op(p, q)
.
case类::
定义了构造函数::(head, tail)
.这允许你像这样匹配:
list match {
case ::(head, tail) =>
}
Run Code Online (Sandbox Code Playgroud)
但是使用中缀运算符模式,您可以编写更熟悉的语法:
list match {
case head :: tail =>
}
Run Code Online (Sandbox Code Playgroud)
请注意,对"[scala]中缀运算符模式"执行stackoverflow搜索会返回类似的问题以及该模式的其他用例.