列表中:::和++之间有什么区别?

5

给定两个列表 aba ::: ba ++ b 有什么区别?我怀疑其中一个运算符只是调用另一个,但实际上,它们的实现看起来完全不同:

def :::[B >: A](prefix: List[B]): List[B] =
  if (isEmpty) prefix
  else if (prefix.isEmpty) this
  else (new ListBuffer[B] ++= prefix).prependToList(this)

override def ++[B >: A, That](that: GenTraversableOnce[B])
                      (implicit bf: CanBuildFrom[List[A], B, That]): That = {
  val b = bf(this)
  if (b.isInstanceOf[ListBuffer[_]])(this ::: that.seq.toList).asInstanceOf[That]
  else super.++(that)
}

从使用角度来看,我应该选择a ::: b还是a ++ b?从实现的角度来看,这两个运算符之一不直接调用另一个的原因是什么?


可能是[Scala列表连接,:::vs ++]的重复问题(https://dev59.com/DGw15IYBdhLWcg3whMI1)。 - om-nom-nom
1个回答

11
区别在于只能在两个列表上使用::: -- 这个操作仅适用于 List 数据类型。由于列表是序列,所以它作为列表的连接运算符。 ++ 方法更为通用 - 它允许创建任意两个集合的联合。这可能是两个集合,此时它作为联合运算符,或者两个序列,此时它作为连接运算符。
对于 2 个列表,++::: 没有语义上的区别 -- :::++ 的变体,用于函数式列表,应该更加熟悉函数式编程人员。
你在 ++ 实现中看到的 if 语句是一种优化 -- 如果这个集合和那个集合都是列表,就使用列表连接运算符:::将这两个列表相加。否则,使用通用的 ++ 实现,将this集合和that集合的所有元素添加到适当的 That 类型的构建器中。
因此,对于列表而言,相关的区别在于性能 -- 对于函数式列表,您不需要像通用的 ++ 实现那样遍历第二个列表 - 只需要重新实例化第一个列表的节点即可创建一个新的函数式列表。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接