在`case class`中有一个`private`构造函数字段是否有意义?

时间:2015-12-16 04:04:03

标签: scala private case-class

我看到一些像这样的Scala代码:

case class Team(private val members: List[User]) {
    def removed(member: User): Team = {
        Team(members.filterNot(_ == member))
    }
    def added(member: User): Team = {
        Team(member :: members)
    }
    def allNames: List[String] = members.map(_.name)
}

您可以看到Teamcase class,但它有一个private字段members。在正文中,它有几种方法来构建新的Team,以及一种方法allNames,它可以导出私有members的一些信息。

我不确定case class的用法是否合适,因为我认为case class是一个数据类,我们不应该使用private字段。对于这种情况,我认为正常的课程就足够了:

class Team(members: List[User]) {
    def removed(member: User): Team = {
        new Team(members.filterNot(_ == member))
    }
    def added(member: User): Team = {
        new Team(member :: members)
    }
    def allNames: List[String] = members.map(_.name)
}

您可以看到我删除了case,还删除了private,因为对于普通类,默认情况下构造函数的字段是私有的。

但是我不确定是否有充分的理由在第一个方法中编写代码。

1 个答案:

答案 0 :(得分:4)

案例类中的私有val有点令人惊讶,因为如果你认为获得该值的其他方法只是语法糖,它们并不像你想象的那样私密。

特别是,模式匹配将为您提供基础值:

whatever match {
  case Team(members) => println("I can see "+members.mkString)
}

该值仍然在平等中发挥作用(即使您无法通过名称获取),并且您可以使用copy创建具有不同值的副本。

有时使用private val来强制执行该类的最佳实践,即仅使用模式匹配来获取值(例如,因为您经常希望模式匹配其他内容,这会强制执行一致性)。有时它表明程序员并不了解它是如何工作的,并认为它强制完全无法访问val。