「明示的に状態を公開する」とは、ケースクラスのことですか?
以下アクターは、値1
で初期化されている可変Set[Int]
、との状態を表し2
、及び3
:
case class State(s: mutable.Set[Int])
case class Add(num: Int)
case class Remove(num: Int)
class MyActor extends Actor {
val state = mutable.Set(1, 2, 3)
def receive = {
case GetState =>
sender ! State(state)
case Add(i) =>
state += i
case Remove(i) =>
state -= i
}
}
このアクターがGetState
メッセージを受信すると、それはでその状態をラップState
ケースクラスを作成し、それを送信者に送信します。 State
ケースクラスが不変であっても、そのパラメータs
は変更可能ですSet
です。したがって、MyActor
がその状態でState
インスタンスを作成し、それをメッセージとしてGetState
メッセージの送信者に送信すると、MyActor
の状態はMyActor
の境界の外側で変更可能になります。具体的には、AnotherActor
がMyActor
にGetState
メッセージを送信したとします。このとき、MyActor
はAnotherActor
に状態を送信します。その状態は、ケースクラス内に送達されても、
class AnotherActor extends Actor {
def receive =>
case State(state) =>
// MyActor's state is exposed here
state -= 2
}
AnotherActor
それから2
を除去することによってMyActor
の状態を変更する:ここで後者の俳優です。
この種のリークを緩和するには、アクタ自体の変更を制限します。この例では、代わりにval state = mutable.Set(1, 2, 3)
を有するので、var state = immutable.Set(1, 2, 3)
定義:それはですので、ここで
class MyActor extends Actor {
var state = immutable.Set(1, 2, 3)
def receive = {
case GetState =>
sender ! state
case Add(i) =>
state = state + i
case Remove(i) =>
state = state - i
}
}
を、MyActor
は安全にメッセージとしてその状態を送信することができます不変Set
(私たちはケースクラス内のSet
をラップすることができますが、それはですこの場合は必須ではありません)。
不変性を達成するために、クラスに「ケース」を書くだけでは不十分ですか?
いいえアクターメッセージングのケースクラスを使用する場合は、クラスのすべてのパラメータ自体が不変であることを確認してください。
また、その使用方法に注意する必要がありますか?
はい。