【问题标题】:akka sending a closure to remote actorakka 向远程参与者发送闭包
【发布时间】:2013-03-22 06:03:54
【问题描述】:

背景

我想向远程参与者发送一个闭包。远程参与者应该对其数据运行闭包并发回结果。 这可能是不可取的,但出于好奇,我现在想这样做

但我观察到,如果将闭包创建为匿名函数,它也会捕获外部对象并尝试对其进行编组,如果外部对象不可序列化,则会失败,如本例所示。

class Client(server: ActorRef) extends Actor {

  var every = 2

  override def preStart() = {
    println("client started. sending message....")
    server ! new Message((x) => x % every == 0)
  }

}

上面的代码在调用远程actor时产生异常。我可以在方法preStart()中定义一个局部变量@

val every_ = every

并使用它来代替actor成员变量。但我觉得这是一种解决方法而不是解决方案。如果闭包有点复杂,我将不得不非常小心。

另一种方法是定义一个继承自Function1[A,B] 的类,并将其实例作为闭包发送。

class MyFunc(every : Int) extends Function1[Int,Boolean] with Serializable {

  def apply(v1 :Int) : Boolean = {
    v1 % every == 0
  }  
}


server ! new Message(new MyFunc(every))

但这将闭包定义与使用它的地方分开,并违背了使用函数式语言的全部目的。并且也使得定义闭包逻辑更加困难。

具体查询

当我从本地定义的闭包创建MyFunc 的实例时,有没有办法可以推迟定义Function1.apply 的主体并分配apply 的主体?

例如

server ! new Message(new MyFunc(every){ // not valid scala code
  x % every == 0
})

every 是一个局部变量?

基本上我想结合这两种方法,即将Function1 的对象发送到远程actor,Function1 的主体由在创建Function1 实例的位置定义的匿名函数定义。

谢谢,

【问题讨论】:

  • 我想你知道你在做什么,但我想确保你知道发送闭包被认为是一种不好的做法,正如 documentation - 段落演员最佳实践 alinea 3 中所明确解释的那样跨度>
  • 感谢您指出。或者,我可以将该行为封装在一个演员中并动态创建它吗?即根据闭包决定actor的行为,而不是将闭包本身发送给actor。
  • 您可以做很多事情,但我感觉您正在尝试针对特定问题实施“错误”/尴尬的解决方案。我相信如果你编辑你的问题并描述你想要达到的目标,你会在 SO 上得到更好的回应
  • 好的。我将问题改写为特定查询。如何动态定义Funtion1[A,B] 's apply() 方法的主体?就像我们在实例化接口时如何在 Java 中定义匿名类方法
  • 谢谢我刚刚检查了确实可以在创建时定义Function1 的主体。谢谢 :)

标签: scala akka actor


【解决方案1】:

当然,你可以将行为发送给演员,但这被认为是一种不好的做法,你的问题是对问题的一个很好的回答:“为什么”。

正如 BGR 指出的那样,documentation 中有关于这个问题的特殊部分,但它没有示例。

因此,当您将闭包作为消息发送时,您会发送一些额外的“隐式”状态。正如文档中所说,它可能不是可变的,但即使在这种情况下,它也会产生问题。

scala 的问题在于它不是严格意义上的函数式语言——它是多范式语言。换句话说,您可以将功能范式的代码与命令式的代码并排。没有这样的问题,比如haskell,纯函数式的。

如果您的“特定查询”,我建议您使用一组预定义函数。这完全等同于带有闭包的变体,但语法有点啰嗦。由于您在运行时不生成代码,因此您使用的所有函数都在有限集合中定义,并且(看起来)按值参数化。这使得你的代码不像闭包那样灵活,但最终它会是等价的情况。

所以,作为我所有帖子的主旨:如果你要向actor发送行为,它应该是坚如磐石的原子(意思是没有任何依赖关系)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 2015-06-15
    相关资源
    最近更新 更多