代码之家  ›  专栏  ›  技术社区  ›  altayseyhan

Scala case类“显式公开状态”

  •  1
  • altayseyhan  · 技术社区  · 8 年前

    阅读时 akka docs 在消息和不变性部分下面,它提到了case类内部的“显式公开状态”。所以我的问题是;

    为了实现不变性,为类编写“case”难道还不够吗? 或者我应该小心它的使用?

    3 回复  |  直到 8 年前
        1
  •  3
  •   Jeffrey Chung    8 年前

    对于case类来说,“显式公开状态”是什么意思?

    下面的参与者用可变变量表示其状态 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
      }
    }
    

    GetState 消息,它将其状态包装在 State case类并将其发送给发送者。即使 case类是不可变的,其参数 s Set . 因此,当 MyActor 状态 消息 的状态在 我的演员 AnotherActor 发送 GetState公司 消息收件人 ,此时 将其状态发送到

    class AnotherActor extends Actor {
      def receive =>
        case State(state) =>
          // MyActor's state is exposed here
          state -= 2
    }
    

    另一位演员 修改 通过删除 即使状态是在case类中传递的,也可以从中获得。

    为了缓解这种泄漏,将可变性限制到参与者本身。在本例中 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
      }
    }
    

    在这里 可以安全地将其状态作为消息发送,因为它是不可变的 设置 设置 在case类中,但这在本例中不是必需的)。

    不可以。当使用case类进行参与者消息传递时,请确保该类的所有参数本身是不可变的。

    或者我应该小心它的使用?

        2
  •  3
  •   HTNW    8 年前

    我相信它指的是做一些像

    case class Broken(m: mutable.Map[String, String])
    

    Broken 表面上是不可变的,因为它的任何字段都不能直接设置为任何值,但仍然可以通过更新来更改 m ,这将导致包含 改变( hashCode , equals 等等),从而打破任何依赖于一致性的东西。 对应于 破碎的 也会发生变异。

        3
  •  1
  •   Brian Agnew    8 年前

    我想你指的是这句话:

    在最简单的形式中,案例类构造函数的参数将映射到“val”字段,因此它们的引用是不可变的。但是,如果字段本身是可变的(例如,引用可变集合或对象) 如果您公开了它(比如通过访问器方法),那么类将变得可变(因为您公开了可变字段)。然而,如果你愿意的话,并不是说你仍然可以在内部改变状态。