list - `::` 和 `+:` 在列表前面有什么区别)?

标签 list scala operators prepend cons

List 有 2 个方法指定用于将元素添加到(不可变)列表:

  • +:(实现 Seq.+:),以及
  • ::(仅在List中定义)

+: 从技术上讲有一个更通用的类型签名 -

def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That
def ::[B >: A](x: B): List[B]

- 但忽略隐式,根据文档消息,仅需要 ThatList[B],签名是等效的。

List.+:List.:: 之间有什么区别?如果它们实际上是相同的,我假设+: 最好避免依赖于具体实现 List。但是为什么要定义另一个公共(public)方法,以及客户端代码何时调用它?

编辑

模式匹配中还有一个 :: 提取器,但我想知道这些特定的方法。

另请参阅:Scala list concatenation, ::: vs ++

最佳答案

确定两种方法之间差异的最佳方法是查看源代码。

source :::

def ::[B >: A] (x: B): List[B] =
  new scala.collection.immutable.::(x, this)

source +::

override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[List[A], B, That]): That = bf match {
  case _: List.GenericCanBuildFrom[_] => (elem :: this).asInstanceOf[That]
  case _ => super.+:(elem)(bf)
}

如您所见,对于 List,两种方法执行相同的操作(编译器将为 CanBuildFrom 参数选择 List.canBuildFrom)。

那么,该使用哪种方法呢?通常人们会选择接口(interface) (+:) 而不是实现 (::),但由于 List 是函数式语言中的通用数据结构,因此有自己的方法并被广泛使用。许多算法都是按照 List 的工作方式构建的。例如,您会发现许多方法将单个元素添加到 List 或调用方便的 headtail 方法,因为所有这些操作都是 O(1)。因此,如果您在本地使用 List(在单个方法或类内),则选择特定于 List 的方法是没有问题的。但如果你想在类之间进行通信,即你想编写一些接口(interface),你应该选择更通用的 Seq 接口(interface)。

关于list - `::` 和 `+:` 在列表前面有什么区别)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11814675/

相关文章:

python - 根据 Python 中的列表元素检查输入

html - 强制边距使用所有宽度

Scala 酸洗 : Writing a custom pickler/unpickler for nested structures

scala - 展平相同类型的嵌套列表

java - 原始数据类型和类数据类型的 equals() 方法和 '==' 运算符

wpf - 接口(interface)/抽象的 XAML 集合 "Could not create an instance"

java - 在遍历列表时按索引从列表中删除项目

java - Scala 中是否有相当于 Python 的 islice 的东西?

MySql REGEXP 运算符

c - 模数 "%"和按位和 "&"的剩余部分计算导致 AVX2 上的结果不同