方法参数中的scala map无法添加键值

时间:2016-11-05 16:16:37

标签: scala

在Scala中,如何将地图作为参考对象传递给方法,以便我可以为此地图添加键值。我试过这段代码,但它没有用。

var rtnMap = Map[Int, String]()
def getUserInputs(rtnMap: Map[Int, String]) {
   rtnMap += (1-> "ss") //wrong here
}

我理解,默认情况下,方法中的参数是val,就像java中的final一样,它可以提供一些安全性。但至少它应该允许我们插入一个新条目。你有什么想法吗?

3 个答案:

答案 0 :(得分:2)

欢迎使用函数式编程

首先,mutable map可以使用您的用例。您已使用immutable map,因为默认情况下Scala中提供了此功能。默认情况下,包scala.Predef中的所有内容都可以在Scala中使用,默认情况下您无需导入它。

下面的代码作为例外工作。

import scala.collection.mutable.Map

val gMap = Map[Int, String]()

def getUserInputs(lMap: Map[Int, String]) = {
   lMap += (1-> "ss")
}

以下通话将更改gMap

的内容
getUserInputs(gMap)

以下是证据

scala> import scala.collection.mutable.Map
import scala.collection.mutable.Map

scala>
     |     val gMap = Map[Int, String]()
gMap: scala.collection.mutable.Map[Int,String] = Map()

scala>
     |     def getUserInputs(lMap: Map[Int, String]) = {
     |        lMap += (1-> "ss")
     |     }
getUserInputs: (lMap: scala.collection.mutable.Map[Int,String])scala.collection.mutable.Map[Int,String]

scala> getUserInputs(gMap)
res2: scala.collection.mutable.Map[Int,String] = Map(1 -> ss)

scala> gMap
res3: scala.collection.mutable.Map[Int,String] = Map(1 -> ss)

在最后一次Scala repl中注意gMap的内容。 gMap包含添加的项目。

常规代码改进

除非你有充分的理由使用它,否则不要使用可变集合。

如果是不可变集合,则在完成更改现有数据结构的操作时会返回新实例。这样,现有的数据结构不会改变。这在很多方面都很好。这可以确保程序的正确性,并确保称为引用透明度(读取它)。

所以你的程序应该理想地像这样

val gMap = Map.empty[String, String] //Map[String, String]()

def getUserInputs(lMap: Map[Int, String]) = {
       lMap += (1-> "ss")
}

val newMap = getUserInputs(gMap)

内容已添加到newMap,旧地图未更改,保持不变。这非常有用,因为持有gMap并访问gMap的代码不必担心底层结构发生的变化。(可以说在多线程场景中,它非常有用。 )

  

保持原始结构的完整性并为更改状态创建新实例是在函数式编程中处理状态的一般方法。因此,理解这一点并实践这一点很重要。

已弃用的语法及其在Scala 2.12中的删除

你宣布你的功能如下

def getUserInputs(lMap: Map[Int, String]) { // no = here
  lMap += (1-> "ss")
}

在上面的函数定义中,闭括号后面没有=。这在Scala 2.12中已弃用。所以不要使用它,因为Scala编译器使用此函数声明语法会产生误导性的编译错误。

正确的方法就是这样。

def getUserInputs(lMap: Map[Int, String]) = { 
 lMap += (1-> "ss")
}

请注意,此语法中有=

答案 1 :(得分:1)

要传递对地图的引用并更改那个地图,您需要使用可变 Map实现(Scala中的默认值是不可变的地图,无论如何它是否被声明为renderScene(props) { const {route} = props.scene ... if (route.key === 'detail') { return <DetailViewComponent goBack={...} itemId={route.itemId} /> } } val),因此可以替代@Esardes的答案(如果var不在范围内也可以使用其中rtnMap的定义是:

getUserInputs

答案 2 :(得分:0)

您可以将值包装在一个对象中,然后将其作为参数传递,或者,如果它在函数范围内可用,则可以直接编写

dimensions=ga:source,ga:medium
metrics=ga:sessions,ga:pageviews,ga:sessionDuration,ga:bounces
segment=dynamic::ga:transactions>1