Dan*_*wak 22
链表由两种情况组成:cons单元(具有头部和尾部)和空列表.这些情况被称为::和NilScala中分别作为与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搜索会返回类似的问题以及该模式的其他用例.