为什么scala列表类名为::

Jef*_*rey 13 scala list

为什么scala列表实现名为::而不是类名?那背后有一些特殊的含义吗?

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搜索会返回类似的问题以及该模式的其他用例.