【问题标题】:What's the difference between :: and +: [duplicate]::和+之间有什么区别:[重复]
【发布时间】:2013-02-20 14:04:44
【问题描述】:
scala> 3 :: List(1,2)
res5: List[Int] = List(3, 1, 2)

scala> 3 +: List(1,2)
res6: List[Int] = List(3, 1, 2)

这两个运算符有什么区别?

【问题讨论】:

标签: scala


【解决方案1】:

List 类上定义的方法+::: 具有following implementations

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)
}

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

方法+:需要存在,因为它继承自SeqLike。正如 pelotom 所说,这是更通用的方法。

但是,我不确定为什么需要存在 List.:: 方法。

更新:同样的问题有already been asked。在 cmets 中建议 :: 方法由于历史原因而存在。

【讨论】:

    【解决方案2】:

    不同之处在于+::: 的抽象,它作用于广义Seqs 而不仅仅是Lists。例如,+: 也适用于 Streams:

    scala> 3 +: Stream(1,2)
    res0: scala.collection.immutable.Stream[Int] = Stream(3, ?)
    

    当您将它与List 一起使用时,它在功能上与:: 相同。

    【讨论】:

    • 那么:: 是否可以被+: 弃用,或者它仍然有用吗?
    • @KiptonBarros 不,因为:: 实际上是一个case 类,它代表List 的“构造函数”(在algebraic data types 的意义上),这意味着它对于定义那种。你可能会争辩说 :: 应该被隐藏,只有 +: 应该被客户端使用,以使代码尽可能通用,但惯例通常是公开抽象数据类型的构造函数,而不是可能会改变(List 永远不会改变,这是一个非常明确的数学对象。)
    • 可能还值得注意的是,+: 是右侧对象上的一个函数,这有点不寻常。这是因为它以冒号结尾——以 : 结尾的函数会按照您期望的方式向后工作。在 scala 集合库中, coll :name object 通常与 object name: coll 相同,但向后除外。例如,List(4) :+ 3 == List(4, 3) 和 3 +: List(4) == List(3, 4)。
    • 这里符号::指的是List类中定义的方法。在其他情况下,:: 也可以引用案例类。
    猜你喜欢
    • 1970-01-01
    • 2021-12-17
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    相关资源
    最近更新 更多