【问题标题】:What's the difference between ::: and ++ for Lists?列表的 ::: 和 ++ 有什么区别?
【发布时间】:2013-04-03 14:58:40
【问题描述】:

给定两个列表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?从实现的角度来看,这些运算符中的一个不简单地调用另一个是否有特定的原因?

【问题讨论】:

标签: list scala operators


【解决方案1】:

不同之处在于您只能在 2 个列表上使用 ::: -- 此操作仅适用于 List 数据类型。由于列表是序列,因此它充当列表的连接运算符。

++ 方法更通用 - 它允许创建任意两个集合的联合。这可能是两个集合,在这种情况下它充当联合,或者两个序列,在这种情况下它充当连接。

++::: 对于 2 个列表没有语义差异 -- :::++ 的变体,对于函数式程序员来说应该看起来更熟悉。

您在++ 实现中看到的if 语句是一种优化——如果this 集合和that 集合都是列表,只需使用列表连接运算符::: 将两个列表相加.否则,使用++ 的通用实现,它将thisthat 集合的所有元素添加到That 类型的适当构建器。

因此,列表的相关区别在于性能——对于功能列表,您不需要像通用 ++ 实现那样遍历第二个列表——只需要重新实例化第一个列表的节点来创建新功能列表。

【讨论】:

    猜你喜欢
    • 2010-11-05
    • 2010-10-12
    • 2012-12-09
    • 1970-01-01
    相关资源
    最近更新 更多