我正在运行Scala 2.10.2。我想创建一个列表,然后在列表中添加一些元素,并期望在调用列表名称时查看列表中的所有元素。但我观察到一些非常奇怪的东西(因为我是新手,至少对我来说很奇怪)。以下是我在sbt console
scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)
scala> l
res0: List[Double] = List(1.0, 5.5)
scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)
scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)
scala> l
res3: List[Double] = List(1.0, 5.5)
scala>
首先,我创建了包含2个元素(1.0和5.5)的列表l
。我打电话给l
并得到我的期望;这两个要素。现在我尝试使用:::
向列表中添加另一个元素,它返回了一个新列表,其中包含我添加的新元素列表(2.2和3.7)Sweet!我甚至检查了其他人的代码以获取帮助:Appending an element to the end of a list in Scala使用新的构造:+
。所以在这个阶段我很高兴,但是我打电话给l
并且我得到了意想不到的结果:`res3:List [Double] = List(1.0,5.5)'。
我添加的元素在哪里?我如何正确添加这些元素,以便当我调用l
时,我得到一个包含我添加的所有内容的新列表?
答案 0 :(得分:44)
您正在使用不可变列表。 List上的操作返回一个新List。旧名单保持不变。如果另一个类/方法持有对原始集合的引用并且依赖于它保持不变,则这非常有用。您可以使用
中的不同命名valval myList1 = 1.0 :: 5.5 :: Nil
val myList2 = 2.2 :: 3.7 :: mylist1
或使用
中的varvar myList = 1.0 :: 5.5 :: Nil
myList :::= List(2.2, 3.7)
这是以下语法的等效语法:
myList = myList.:::(List(2.2, 3.7))
或者您可以使用其中一个可变集合,例如
val myList = scala.collection.mutable.MutableList(1.0, 5.5)
myList.++=(List(2.2, 3.7))
不要与不修改原始可变列表的以下内容混淆,但返回一个新值:
myList.++:(List(2.2, 3.7))
但是,您应该只在性能关键代码中使用可变集合。不可变集合更容易推理和使用。一个很大的优点是不可变List和scala.collection.immutable.Vector是Covariant。如果这对您没有任何意义,请不要担心。它的优点是你可以在不完全理解它的情况下使用它。因此,您默认使用的集合实际上是scala.collection.immutable.List,它只是自动为您导入。
我倾向于使用List作为我的默认集合。从2.12.6 Seq默认为不可变的Seq,在此之前它默认为不可变。
答案 1 :(得分:11)
如果您真的需要变异,请使用import scala.collection.mutable.MutableList或类似物。
import scala.collection.mutable.MutableList
val x = MutableList(1, 2, 3, 4, 5)
x += 6 // MutableList(1, 2, 3, 4, 5, 6)
x ++= MutableList(7, 8, 9) // MutableList(1, 2, 3, 4, 5, 6, 7, 8, 9)
答案 2 :(得分:8)
我将尝试解释您尝试过的所有命令的结果。
scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)
首先,List
是scala.collection.immutable.List
的类型别名(在Predef.scala中定义)。
使用List伴随对象是实例化List
的更直接的方法。例如:List(1.0,5.5)
scala> l
res0: List[Double] = List(1.0, 5.5)
scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)
:::
返回由给定列表前缀和此列表
未修改原始列表
scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)
List(l)
是List[List[Double]]
绝对不是你想要的。
:+
返回一个新列表,其中包含此列表的所有元素,后跟elem。
类型为List[Any]
,因为它是List[Double]
和Double
scala> l
res3: List[Double] = List(1.0, 5.5)
l未被修改,因为immutable.List
上的方法没有修改List。
答案 3 :(得分:1)
由于您要将元素附加到现有列表,因此可以使用var List [Int],然后继续将元素添加到同一列表中。 注 - >您必须确保将元素插入现有列表,如下所示: -
var l:List [int] = List()//创建一个空列表
l = 3 :: l //将3添加到列表的头部
l = 4 :: l //使int 4成为列表的头部
//现在当你打印l时,你会看到列表中的两个元素(4,3)