【问题标题】:Scala case class and private constructor elementScala案例类和私有构造函数元素
【发布时间】:2013-12-30 05:07:51
【问题描述】:

我希望能够跟踪在某个状态机中完成的任务数(使用 Akka FSM),这就像加入 N 个动作,开始于从状态 A 到 B 的转换,在状态 B。所以当所有事件都达到 FSM 时状态 B - 进入状态 C。

我为 fork/join 状态创建了非常简单的跟踪器。

  sealed trait ForkJoin {

    def join(): ForkJoin

  }

  case class Forks(forkNum: Int) extends ForkJoin {

    private var finished: Int = 0

    override def join = if (finished + 1 == forkNum) JoinComplete
    else {
      val f = Forks(forkNum)
      f.finished = finished + 1
      f
    }

  }

  case object JoinComplete extends ForkJoin {

    override def join = JoinComplete

  }

我不喜欢那里 - var finished 的感觉。它的本质是 val,但是我不知道如何制作私有 val 并在 join 方法中对其进行初始化。

我认为有一些方法可以将构造函数参数设置为 private,不能从外部访问 - 但这不起作用。

【问题讨论】:

    标签: scala case-class


    【解决方案1】:

    不能将私有参数传递给case classes。这没有任何意义,因为案例类实例的身份是通过传递的构造函数参数定义的。私有构造函数参数会改变状态,但不会影响相等比较或模式匹配。

    你可以做的是让整个构造函数private。要作为 FSM 状态正常运行,您可能需要在自己的 [1] 上实现 equals 和 hashCode。

    sealed trait ForkJoin {
      def join(): ForkJoin
    }
    
    case class Forks private(forkNum: Int, finished: Int) extends ForkJoin{
    
      override def join =
        if (finished + 1 == forkNum)
          JoinComplete
        else
          Forks(forkNum, finished + 1)
    
      def copy(forkNum: Int = this.forkNum) = 
        Forks(forkNum, finished)
    
    }
    
    object Forks{
      def apply(forkNum: Int): Forks = Forks(forkNum, 0)
    }
    
    object JoinComplete extends ForkJoin {
      override def join = JoinComplete
    }
    

    【讨论】:

    • 但这将允许我创建一个 Forks 的实例,该实例具有“已完成”的任意值,我想避免这种情况。
    • 我相应地改变了答案,这个更合适吗?
    【解决方案2】:

    类似的东西?

    sealed trait ForkJoin {
        def join(): ForkJoin
     }
    
      case class Forks(forkNum: Int, finished: Int = 0) extends ForkJoin {
        override def join = if (finished + 1 == forkNum) JoinComplete
        else Forks(forkNum, finished + 1)
       }
    
      case object JoinComplete extends ForkJoin {
        override def join = JoinComplete
      }
    

    【讨论】:

    • (虽然我认为你在 trait 和 object 中的 join() 方法也可以返回 this)
    • 通过这种方式,可以覆盖对象中的当前连接数并将其传递给状态,这是我真正想避免的。
    猜你喜欢
    • 1970-01-01
    • 2020-05-16
    • 2011-01-24
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多