在消息和不变性部分正确阅读akka docs时,它提到"明确暴露国家"内部案例类。所以我的问题是;
谚语"明确暴露国家"是什么意思?案例类?
为了实现不变性,还不足以写出" case"一堂课? 或者我应该小心它的用法?
答案 0 :(得分:3)
我认为它指的是做类似
的事情case class Broken(m: mutable.Map[String, String])
Broken
表面上是不可变的,因为它的所有字段都不能直接设置为任何字段,但它仍然可以通过更新m
来更改,这将导致包含Broken
的行为改变(hashCode
,equals
等),从而打破任何依赖于那些一致的东西。 m
对应于Broken
的内部(可变)状态,并且公开它也允许Broken
进行变异。
答案 1 :(得分:3)
对于案例类,“明确暴露国家”是什么意思?
下面的演员用可变Set[Int]
表示其状态,该状态使用值1
,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
}
}
当此actor收到GetState
消息时,它将其状态包装在State
case类中,并将其发送给发送方。尽管State
案例类是不可变的,但其参数s
是可变的Set
。因此,当MyActor
创建具有其状态的State
实例并将其作为消息发送给GetState
消息的发件人时,MyActor
的状态将变为可修改的MyActor
本身的边界。为了具体说明,我们要说AnotherActor
向GetState
发送MyActor
条消息,此时MyActor
将其状态发送到AnotherActor
。这是后者:
class AnotherActor extends Actor {
def receive =>
case State(state) =>
// MyActor's state is exposed here
state -= 2
}
AnotherActor
通过删除MyActor
来修改2
的状态,即使该状态是在案例类中传递的。
为了缓解这种泄漏,限制对actor本身的可变性。在此示例中,不是使用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
包装在一个案例类中,但在这种情况下这不是必需的)
为了实现不变性,为一个班级写“案例”是不够的?
没有。使用case类进行actor消息传递时,请确保所有类的参数本身都是不可变的。
或者我应该注意它的用法?
是
答案 2 :(得分:0)
我认为你引用了这个特别的引用:
Scala案例类是不可变的(如果没有显式公开) 国家)
在最简单的形式中,案例类构造函数的参数将映射到' val'字段因此它们的引用将是不可变的。但是,如果字段本身是可变的(例如引用可变集合或对象)和,那么(通过访问器方法,例如),那么该类将变得可变(因为您已经暴露了)一个可变的领域)。但是,如果你愿意的话,并不是说你仍然可以在内部改变状态。