我看到一些像这样的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)
}
您可以看到Team
是case 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
,因为对于普通类,默认情况下构造函数的字段是私有的。
但是我不确定是否有充分的理由在第一个方法中编写代码。
答案 0 :(得分:4)
案例类中的私有val有点令人惊讶,因为如果你认为获得该值的其他方法只是语法糖,它们并不像你想象的那样私密。
特别是,模式匹配将为您提供基础值:
whatever match {
case Team(members) => println("I can see "+members.mkString)
}
该值仍然在平等中发挥作用(即使您无法通过名称获取),并且您可以使用copy
创建具有不同值的副本。
有时使用private val
来强制执行该类的最佳实践,即仅使用模式匹配来获取值(例如,因为您经常希望模式匹配其他内容,这会强制执行一致性)。有时它表明程序员并不了解它是如何工作的,并认为它强制完全无法访问val。