バックグラウンド
リモートアクターにクロージャーを送信したい。リモートアクターは、そのデータに対してクロージャーを実行し、結果を送り返す必要があります。 お勧めできないかもしれませんが、好奇心のために今やりたいことです
しかし、クロージャが無名関数として作成された場合、外部オブジェクトもキャプチャしてマーシャリングしようとしますが、この場合のように、外部オブジェクトがシリアル化できない場合は失敗します。
class Client(server: ActorRef) extends Actor {
var every = 2
override def preStart() = {
println("client started. sending message....")
server ! new Message((x) => x % every == 0)
}
}
上記のコードは、リモートアクターの呼び出し中に例外を生成します。メソッドでローカル変数を定義できますpreStart()
val every_ = every
アクターメンバー変数の代わりに使用します。しかし、それは解決策ではなく回避策だと思います。クロージャーがもう少し複雑な場合は、非常に注意する必要があります。
別の方法は、インスタンスを継承してクラスを定義し、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))
しかし、これはクロージャーの定義をそれが使用される場所から分離し、関数型言語を使用するという目的全体を無効にします。また、クロージャロジックの定義がより困難になります。
特定のクエリ
ローカルで定義されたクロージャからのインスタンスを作成するときに、の本体の定義を延期し、の本体Function1.apply
を割り当てる方法はありますか?apply
MyFunc
例えば
server ! new Message(new MyFunc(every){ // not valid scala code
x % every == 0
})
every
ローカル変数はどこにありますか?
基本的に、2つのアプローチを組み合わせたいと思います。つまり、インスタンスが作成される場所で定義されたanon関数によって定義されたFunction1
本体を使用して、リモートアクターにoverのオブジェクトを送信します。Function1
Function1
ありがとう、