Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala-如何避免关闭?_Scala_Closures - Fatal编程技术网

Scala-如何避免关闭?

Scala-如何避免关闭?,scala,closures,Scala,Closures,如何在将函数作为参数传递给类构造函数时避免闭包 我的类构造函数接受类型为()=>Unit的函数。在程序工作过程中,我希望从可变映射访问一个键值对,该映射在使用构造函数创建对象时未定义 val cats = scala.collection.mutable.Map[String, Cat] class Trigger(period: Long, f: () => Unit) { //pseudocode: when period passes, f() } someWonde

如何在将函数作为参数传递给类构造函数时避免闭包

我的类构造函数接受类型为
()=>Unit
的函数。在程序工作过程中,我希望从可变映射访问一个键值对,该映射在使用构造函数创建对象时未定义

val cats = scala.collection.mutable.Map[String, Cat]

class Trigger(period: Long, f: () => Unit) {

  //pseudocode:
  when period passes, f()

}

someWonderfulObject += new Trigger (1000, () => cats("Hershy").meow)

cats += ("Hershy" -> Cat())
然后,当奇妙的对象触发它的触发器时,我得到一个错误,没有像“Hershy”这样的键。我的结论是,这显然是由于传递给
触发器的
f
在没有“Hershy”的状态下被关闭

我现在的问题是-如何避免Scala在这里使用闭包,而是查看
cats
的实际状态

更新:

“期间结束时”的代码如下:

tpf的
tpf
值来自上面,所以在这里所有这些看起来都正常

更新:

我发现问题出在另一个完全不相关的地方,我把所有这些东西的容器弄糊涂了。不过,谢谢大家,我从答案中学到了一些东西。

闭包不会做这样的事情(这很难指定,性能很差,而且会使整个事情变得毫无用处)。闭包可能包含对cats的引用,或者包含cats的实例的引用,而不是副本

此代码按预期工作:

val cats = collection.mutable.Map[String, String]()

class Trigger(name: String, f: () => Unit) {
  def fire = {
    println("Fire " + name)
    f()
  }
}

val trigger = new Trigger("calling Hershy", () => println(cats("Hershy")))
cats += "Hershy" -> "meow"
trigger.fire // prints Fire calling Hershy
关闭不是错误,我怀疑这是您的样本中没有出现的东西

闭包不会做这样的事情(这很难指定,性能很差,而且会使整个事情变得毫无用处)。闭包可能包含对cats的引用,或者包含cats的实例的引用,而不是副本

此代码按预期工作:

val cats = collection.mutable.Map[String, String]()

class Trigger(name: String, f: () => Unit) {
  def fire = {
    println("Fire " + name)
    f()
  }
}

val trigger = new Trigger("calling Hershy", () => println(cats("Hershy")))
cats += "Hershy" -> "meow"
trigger.fire // prints Fire calling Hershy

关闭不是错误,我怀疑这是您的样本中没有出现的东西

你的猫是一个
val
持有对可变集合的引用。闭包不会克隆对象,理论上它只能复制
cats
(引用)的值。但是既然
cats
是一个
val
,换句话说,这是一个常量,这不会是任何问题的根源。顺便问一下,这个如何编译:
(“Hershy”->Cat)
Cat
是一个类,而不是
Cat
本身。我猜这只是伪代码——当其他人试图调试他们从未见过的代码时,它总是混淆事情。哦,对不起,这意味着是Cat(),您的代码行为对时间敏感,线程不安全。您正在修改映射,然后从另一个线程读取它。不能保证添加映射项的代码必须在时间触发器之前执行,即使执行了,也不能保证计时器线程会观察到更改。目前还不清楚这是否是您的直接问题。请在时段结束时显示
的代码。请注意,如果此代码阻塞,则整个时间都将花费在
新触发器
调用期间,因此,您的地图填充代码甚至尚未执行!你的猫是一个
val
持有对可变集合的引用。闭包不会克隆对象,理论上它只能复制
cats
(引用)的值。但是既然
cats
是一个
val
,换句话说,这是一个常量,这不会是任何问题的根源。顺便问一下,这个如何编译:
(“Hershy”->Cat)
Cat
是一个类,而不是
Cat
本身。我猜这只是伪代码——当其他人试图调试他们从未见过的代码时,它总是混淆事情。哦,对不起,这意味着是Cat(),您的代码行为对时间敏感,线程不安全。您正在修改映射,然后从另一个线程读取它。不能保证添加映射项的代码必须在时间触发器之前执行,即使执行了,也不能保证计时器线程会观察到更改。目前还不清楚这是否是您的直接问题。请在时段结束时显示
的代码。请注意,如果此代码阻塞,则整个时间都将花费在
新触发器
调用期间,因此,您的地图填充代码甚至尚未执行!很好的例子,但永远不要忘记猫“喵喵”;-)你忘了那个关键的一点,除了打印“火叫赫希”,它还打印“喵喵”;如果没有“喵”这个词,你的答案就不会是一个简单的例子,它是……一个很好的例子,但永远不要忘记猫“喵”;-)你忘了那个关键的一点,除了打印“火叫赫希”,它还打印“喵喵”;如果没有“喵喵”的话,你的答案就不会是一个简单的例子,它是。。。