鉴于两个列表a
和b
,a ::: b
和a ++ 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
?从实现的角度来看,是否有一个特定的原因,为什么其中一个运算符不会简单地调用另一个?
答案 0 :(得分:11)
不同之处在于您只能在2个列表上使用:::
- 此操作仅适用于List
数据类型。由于列表是序列,因此它充当列表的连接运算符。
++
方法更通用 - 它允许创建任意两个集合的并集。这可能是两组,在这种情况下,它充当一个联合,或两个序列,在这种情况下,它充当连接。
对于2个列表,++
和:::
之间没有语义差异 - :::
是函数列表++
的变体,对功能程序员来说应该更熟悉
您在if
实现中看到的++
语句是一种优化 - 如果this
集合和that
集合都是列表,只需使用list concatenation operator { {1}}将两个列表一起添加。否则,请使用:::
的通用实现,该实现将++
和this
集合的所有元素添加到类型that
的相应构建器中。
因此,列表的相关差异是性能 - 对于功能列表,您不需要像通用That
实现那样遍历第二个列表 - 只需要将第一个列表中的节点重新实例化为创建一个新的功能列表。