我是scala的新手,只是尝试了一些东西,下面是我正在尝试的事情
scala> var col = List[String]()
col: List[String] = List()
scala> List("a", "b", "c").foreach(x => x :: col)
scala> println(col)
List()
实际上,我期待col包含a,b,c,我错过了什么?
答案 0 :(得分:6)
您需要foreach
scala> var col = List[String]()
col: List[String] = List()
scala> List("a", "b", "c").foreach(x => {col = x :: col})
scala> col
res0: List[String] = List(c, b, a)
操作x :: col
只返回一个新列表,其中包含x
前面的元素col
,原始col
不会更改。您需要将col
重新分配给此新生成的列表。
但请注意,由于您使用的是副作用,因此通常不会将其视为惯用的Scala。
答案 1 :(得分:6)
列表中的::
方法不会向列表中添加任何内容,它会创建一个包含前置值的新列表,您将丢弃此新列表,而不是将其重新分配给col
。 x => col = x :: col
会将您列表中的每个元素添加到col
。请注意,col
将为列表(“c”,“b”,“a”),订单相反,因为您要将元素预先挂起到col
。
请注意foreach
不返回任何内容,专为副作用操作而设计。如果您只是想将一个集合转换或将元素加载到另一个集合中,那么可以使用更好的方法。
对于您的特定操作,最合适的方法是foldRight
,它以相反的顺序(从右到左)迭代元素。我们希望在此反向迭代,因为当您将元素一次添加到列表中时,订单会反转。
val col = List("a", "b", "c").foldRight(List[String]())((x, acc) => x :: acc)
将生成List("a", "b", "c")
。这样做的好处是我们不再需要使用var
来声明一个可变变量,事实上我们不会
需要提前声明我们的清单。
请注意,我们可以使用一些特殊语法来保存一些输入
val col = List("a", "b", "c").foldRight(List[String]())(_ :: _)
下划线为我们提供了更短的语法来编写函数文字,我将由您决定是否更清楚。