[英]Is it possible to have a map of {key -> function call} in Scala?
我正在尝试创建一个具有键映射 - >函数调用的类,并且以下代码的行为与我希望的不同。
class MyClass {
val rnd = scala.util.Random
def method1():Double = {
rnd.nextDouble
}
def method2():Double = {
rnd.nextDouble
}
def method3():Double = {
rnd.nextDouble
}
def method4():Double = {
rnd.nextDouble
}
def method5():Double = {
rnd.nextDouble
}
var m = Map[String,Double]()
m += {"key1"-> method1}
m += {"key2"-> method2}
m += {"key3"-> method3}
m += {"key4"-> method4}
m += {"key5"-> method5}
def computeValues(keyList:List[String]):Map[String,Double] = {
var map = Map[String,Double]()
keyList.foreach(factor => {
val value = m(factor)
map += {factor -> value}
})
map
}
}
object Test {
def main(args : Array[String]) {
val b = new MyClass
for(i<-0 until 3) {
val computedValues = b.computeValues(List("key1","key4"))
computedValues.foreach(element => println(element._2))
}
}
}
以下输出
0.022303440910331762
0.8557634244639081
0.022303440910331762
0.8557634244639081
0.022303440910331762
0.8557634244639081
表示一旦将函数放入映射中,它就是一个冻结的实例(每个键为每个传递生成相同的值)。 我希望看到的行为是键将引用函数调用,生成新的随机值而不是仅返回映射中保存的实例。
问题在于你的地图m
的签名。 你描述了你想把函数放在地图中; 但是你已经将它声明为Map[String, Double]
,它只是一个Map[String, Double]
字符串的地图。 正确的类型是Map[String, () => Double]
。
因为括号在无参数方法调用中是可选的,所以这里类型的差异非常重要。 在填充地图时,在插入时调用方法以匹配类型签名(我相信这是通过隐式转换完成的,但我不是100%确定)。
通过简单地更改地图的声明签名,可以根据需要插入函数,并且可以在computeValues
期间computeValues
(需要在第35行上进行更改以map += {factor -> value()}
),从而产生以下输出(在Scala 2.8上测试):
0.662682479130198
0.5106611727782306
0.6939805749938253
0.763581022199048
0.8785861039613938
0.9310533868752249
您需要将键映射到函数,而不是映射到函数会给您的答案。 尝试这个:
var m = Map[String,() => Double]()
m += /* etc. */
m.values.foreach(println(x => x()))
m.values.foreach(println(x => x()))
我会使用scala的类型推断来定义地图。 如果它们仅通过地图使用,则无需单独定义方法。 您也可以使用不可变的val,而不是可变的var。
val m = Map( "key1" -> {() => rnd.nextDouble},
"key2" -> {() => rnd.nextDouble},
"key3" -> {() => rnd.nextDouble},
"key4" -> {() => rnd.nextDouble},
"key5" -> {() => rnd.nextDouble})
您还需要将第35行更改为value()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.