Scala 案例 class "explicitly exposing the state"
Scala case class "explicitly exposing the state"
在消息和不变性部分正下方阅读 akka docs 时,它提到 "explicitly exposing the state" 内部案例 class。所以我的问题是;
案例 class 说 "explicitly exposing the state" 是什么意思?
为了实现不变性,给一个class写"case"不就行了吗?
或者我应该小心它的使用?
我相信它指的是做类似的事情
case class Broken(m: mutable.Map[String, String])
Broken
从表面上看是不可变的,因为它的 none 字段可以直接设置为任何东西,但它仍然可以通过更新 m
来改变,这将导致行为包含 Broken
的更改(hashCode
、equals
等),从而打破任何依赖于一致的东西。 m
对应于 Broken
的内部(可变)状态,公开它也允许 Broken
发生变异。
我想你指的是这句特别的话:
Scala case classes which are immutable (if you don’t explicitly expose
the state)
在最简单的形式中,case class 构造函数的参数将映射到 'val' 字段,因此它们的引用将是不可变的。但是,如果字段本身是可变的(例如,引用可变集合或对象)and 你公开它(比如通过访问器方法),那么 class 将变得可变(因为你暴露了一个可变字段)。并不是说您仍然可以在内部更改状态,但是,如果您愿意的话。
What is meant by saying "explicitly exposing the state" for case class?
下面的 actor 用一个可变的 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
案例 class 中并将其发送给发送者。尽管 State
案例 class 是不可变的,但它的参数 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
的状态,即使该状态是在案例 class.
中传递的
为了减轻这种泄漏,将可变性限制在 actor 本身。在此示例中,定义 var state = immutable.Set(1, 2, 3)
:
而不是 val state = mutable.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
包装在一个案例 class 中,但那是在这种情况下不是必需的)。
In order to achieve immutability, isn't it enough to write "case" for a class?
没有。当使用 case class 进行 actor 消息传递时,请确保所有 class 的参数本身都是不可变的。
Or I should be careful about its usage?
是的。
在消息和不变性部分正下方阅读 akka docs 时,它提到 "explicitly exposing the state" 内部案例 class。所以我的问题是;
案例 class 说 "explicitly exposing the state" 是什么意思?
为了实现不变性,给一个class写"case"不就行了吗? 或者我应该小心它的使用?
我相信它指的是做类似的事情
case class Broken(m: mutable.Map[String, String])
Broken
从表面上看是不可变的,因为它的 none 字段可以直接设置为任何东西,但它仍然可以通过更新 m
来改变,这将导致行为包含 Broken
的更改(hashCode
、equals
等),从而打破任何依赖于一致的东西。 m
对应于 Broken
的内部(可变)状态,公开它也允许 Broken
发生变异。
我想你指的是这句特别的话:
Scala case classes which are immutable (if you don’t explicitly expose the state)
在最简单的形式中,case class 构造函数的参数将映射到 'val' 字段,因此它们的引用将是不可变的。但是,如果字段本身是可变的(例如,引用可变集合或对象)and 你公开它(比如通过访问器方法),那么 class 将变得可变(因为你暴露了一个可变字段)。并不是说您仍然可以在内部更改状态,但是,如果您愿意的话。
What is meant by saying "explicitly exposing the state" for case class?
下面的 actor 用一个可变的 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
案例 class 中并将其发送给发送者。尽管 State
案例 class 是不可变的,但它的参数 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
的状态,即使该状态是在案例 class.
为了减轻这种泄漏,将可变性限制在 actor 本身。在此示例中,定义 var state = immutable.Set(1, 2, 3)
:
val state = mutable.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
包装在一个案例 class 中,但那是在这种情况下不是必需的)。
In order to achieve immutability, isn't it enough to write "case" for a class?
没有。当使用 case class 进行 actor 消息传递时,请确保所有 class 的参数本身都是不可变的。
Or I should be careful about its usage?
是的。