::和+:之间有什么区别?

242 浏览
0 Comments

::和+:之间有什么区别?

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

0
0 Comments

问题的出现原因是对于List类的两个方法+:和::的存在以及它们的实现方式的疑惑。这两个方法的实现可以在List类的源代码中找到。其中+:方法的实现如下:

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)

根据pelotom的说法,+:方法的存在是因为它是从SeqLike继承而来的,这是一个更通用的方法。然而,不清楚为什么::方法需要存在。

更新:同样的问题已经被问过了。在评论中某些情况下::方法的存在是出于历史原因。

解决方法暂时没有给出。

0
0 Comments

::和+:的区别在于,+:是对::的抽象,它作用于广义的Seq而不仅仅是List。例如,+:也适用于Stream。当在List上使用时,它在功能上与::是相同的。

那么::是否可以被+:取代,或者它们还有不同的用途呢?

不,因为::实际上是一个代表List的“构造函数”的case class,这意味着它在该类型的定义中非常重要。或许可以主张隐藏::,只让客户端使用+:,以保持代码尽可能通用,但通常约定是公开抽象数据类型的构造函数(List永远不会改变,它是一个非常明确的数学对象)。

值得注意的是,+:作为右侧对象的一个函数是有点不寻常的。这是因为它以冒号结尾--以冒号结尾的函数的工作方式与预期相反。在Scala集合库中,coll:name object通常与object name: coll相同,只是反过来。例如,List(4):+ 3 == List(4, 3),而3 +:List(4) == List(3, 4)。

这里的符号::指的是定义在List类中的方法。在其他上下文中,::也可以指代case class。

0