5

给定两个列表aand , andb有什么区别?我怀疑其中一个运算符会简单地调用另一个,但实际上,实现看起来完全不同:a ::: 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?从实现的角度来看,这些运算符中的一个不简单地调用另一个是否有特定的原因?

4

1 回答 1

11

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

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

++:::for 2 个列表在语义上没有区别——:::是函数式列表的变体,++对于函数式程序员来说应该更熟悉。

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

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

于 2013-04-11T12:17:03.123 回答