与Actors一起使用时的Scala变量绑定

roy*_*ush 5 closures scala actor akka

我对Scala相当新鲜.我试图理解当一个闭包作为消息的一部分传递给Actor时scala是否进行动态绑定.

我正在使用带有Scala 2.9的Akka 1.2.

我有以下代码段(修改自http://gleichmann.wordpress.com/2010/11/15/functional-scala-closures/)

var minAge = 18
val isAdult = (age: Int) => age >= minAge

actor ! answer(19, isAdult) 
minAge = 20
actor ! answer(19, isAdult)
Run Code Online (Sandbox Code Playgroud)

在actor方面,它只是将isAdult应用于第一个参数并打印结果.由于Scala使用动态绑定(所以我被告知),我原以为

true
false
Run Code Online (Sandbox Code Playgroud)

但不知何故结果是

false
false
Run Code Online (Sandbox Code Playgroud)

因此,scala是静态绑定变量并将18作为两个答案消息的minAge值,这是真的吗?有没有办法在消息中使用闭包时保持动态绑定行为?

谢谢!

Nei*_*ssy 9

您对闭合的理解是正确的.它正在进行动态绑定,但是你引入了并发问题.闭包绑定到可变数据,这使得闭包可变.当您在actor之间传递严格不可变数据时,actor模型仅解决并发问题.您可以按看似按时间顺序编写它,但演员调度程序会更改事件的顺序.由于isAdult是可变的,重新排序会改变结果.

actor ! answer(19, isAdult) // message put in actor queue
minAge = 20
actor ! answer(19, isAdult) // message put in actor queue
// later...
// actor handles answer(19, isAdult)
// actor handles answer(19, isAdult)
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的,但请记住永远不要那样做;-)说真的,如果你想在它们之间共享可变状态,你就不会使用actor.不幸的是,Scala没有提供关闭"按值"的方法,所以你唯一能做的就是手动确保你关闭的所有内容都是`val`. (2认同)