`::`和`+:`之间有什么区别? [英] What's the difference between `::` and `+:` for prepending to a list)?

查看:2928
本文介绍了`::`和`+:`之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

List有2种方法,可以指定将元素添加到(不可变的)列表的前面:

List has 2 methods that are specified to prepend an element to an (immutable) list:

  • +:(实现Seq.+:)和
  • ::(仅在List中定义)
  • +: (implementing Seq.+:), and
  • :: (defined only in List)

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

+: technically has a more general type signature—

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

-但忽略了隐式,根据doc消息,只需要将That设置为List[B]即可,签名是等效的.

—but ignoring the implicit, which according to the doc message merely requires That to be List[B], the signatures are equivalent.

List.+:List.::有什么区别?如果它们实际上是相同的,我认为根据具体实现List,最好避免使用+:.但是,为什么要定义另一个公共方法,客户端代码何时会调用它呢?

What is the difference between List.+: and List.::? If they are in fact identical, I assume +: would be preferred to avoid depending on the concrete implementation List. But why was another public method defined, and when would client code call it?

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

There is also an extractor for :: in pattern matching, but I'm wondering about these particular methods.

另请参见: Scala列表串联,::: vs ++

推荐答案

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

The best way to determine the difference between both methods is to look it the source code.

(:::

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

(+::

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,这两种方法都做同样的事情(编译器将选择

As you can see, for List, both methods do one and the same (the compiler will choose List.canBuildFrom for the CanBuildFrom argument).

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

So, which method to use? Normally one would choose the interface (+:) than the implementation (::) but because List is a general data structure in functional languages it has its own methods which are widely used. Many algorithms are build up the way how List works. For example you will find a lot of methods which prepend single elements to List or call the convenient head or tail methods because all these operations are O(1). Therefore, if you work locally with a List (inside of single methods or classes), there is no problem to choose the List-specific methods. But if you want to communicate between classes, i.e. you want to write some interfaces, you should choose the more general Seq interface.

这篇关于`::`和`+:`之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆