"to close over the enclosing scope/class"是什么意思?



Akka文档记录了使用Props:的危险变体

// NOT RECOMMENDED within another actor:
// encourages to close over enclosing class
val props7 = Props(new MyActor)

然后继续陈述:

不建议在其他参与者中使用此方法,因为它鼓励关闭封闭范围,导致不可序列化的Props和可能的竞争条件(破坏演员封装)。

有人能解释一下"封闭范围"的含义吗?到处找都找不到。谢谢

在这个例子中,new Actor作为一个所谓的"by name"参数传入有点棘手。把它想象成一个() => Actor类型的函数。在重新启动过程中,每当参与者的主管(重新)创建时,都会调用此函数。

问题是,这个函数是一个"闭包"(对谷歌来说很容易;),这意味着它可以捕获并记住周围范围内所需的一切(有时,但很少被称为"堆栈剥离")。例如val f = (a: Int) => a + xx从哪里来?它来自周围的范围。分配给f的函数litetal被称为"开放项"。在运行时,函数文字变成了一个函数值(这是"对象"的一种奇特说法),当执行时,它关闭了开放项,同时捕获了周围范围中的所有内容。这就是"闭包"这个名字的由来。

闭包非常有用,但你必须小心你的闭包。有时xdef或上帝保佑var,这会导致f的结果不可预测,因为您无法控制调用/执行f的时间。试试看!

阿卡有两个非常常见的反家长主义者:

  1. 创建Actor时关闭(外部)this引用来自内部类
  2. 响应时关闭def sender带着未来的信息

顺便说一句,我故意给你谷歌提供了一堆花哨的术语。)

欢呼和快乐编码

作为@agilesteel精细答案的补充,一些参考文献:

解释闭包是什么:Scala编程,8.7,闭包

解释为什么闭包会导致序列化问题:SIP-21-孢子

下面是一个创建Props对象的代码示例,该对象由于关闭了一个不可序列化的对象而不可序列化,基于SIP-21中的示例:

case class Helper(name: String)
object MyNonserializableObject {
    val helper = Helper("the helper")
    val props7 = Props(new MyActor(helper))
}

尽管helper本身是可序列化的,但"new MyActor(helper)"是按名称传递的,因此会捕获this.helper,而this是不可序列化的。

您可以看到actor参数是通过Propsapply方法签名的名称传递的,其中有⇒在creator参数中:

def apply[T <: Actor](creator: ⇒ T)(implicit arg0: ClassTag[T]): Props

最新更新