方法参数中的scala映射不能添加键值

方法参数中的scala映射不能添加键值,scala,Scala,在Scala中,如何将映射作为引用对象传递给方法,以便向该映射添加键值。我试过这个代码,它不起作用 var rtnMap = Map[Int, String]() def getUserInputs(rtnMap: Map[Int, String]) { rtnMap += (1-> "ss") //wrong here } 我理解,默认情况下,方法中的参数是val,就像java中的final一样,它可以提供一些安全性。但至少它应该允许我们插入一个新条目。你有什么想法吗?你可以将你

在Scala中,如何将映射作为引用对象传递给方法,以便向该映射添加键值。我试过这个代码,它不起作用

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

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

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

def getUserInputs = {
   rtnMap += (1-> "ss") 
}

要传递对映射的引用并更改该映射,您需要使用可变映射实现(Scala中的默认值是一个不可变映射,不管它是声明为
val
还是
var
),因此可以使用(如果
rtnMap
不在定义了
getUserInputs
的范围内,也可以使用的方法是:

import scala.collection.mutable

def getUserInputs(map: mutable.Map[Int, String]) {
  map += (1 -> "ss") // mutating "map"
}

val rtnMap = mutable.Map[Int, String]() // notice this can be a val
getUserInputs(rtnMap)
println(rtnMap)
// Map(1 -> ss)
欢迎来到函数式编程 首先,您的用例可以使用
可变映射
。您可以使用
不可变映射
,因为这在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")
}

注意这个语法中有
=

你真的需要吗?试着接受不可变的集合。