在 `case class` 中有一个 `private` 构造函数字段有意义吗?
Does it make sense to have a `private` constructor field in a `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)
}
您可以看到 Team
是一个 case class
,但它有一个 private
字段 members
。并且在主体中,它有几个方法来构造一个新的Team
,还有一个方法allNames
导出私有members
的一些信息。
我不确定case class
的用法是否好,因为我认为case class
是一个数据class,我们不应该使用private
字段.对于这种情况,我认为正常的 class 就足够了:
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
因为对于正常的 class,构造函数的字段默认是私有的。
但我不确定是否有任何充分的理由在第一种方法中编写代码。
case classes 中的私有值有点令人惊讶,因为它们并不像您想象的那样私有,如果您认为其他获取该值的方法只是语法糖的话。
特别是,模式匹配将为您提供基础值:
whatever match {
case Team(members) => println("I can see "+members.mkString)
}
并且该值仍然在平等中发挥作用(即使您无法通过名称获取它),并且您可以使用 copy
.
创建具有不同值的副本
有时 private val
用于强制执行 class 的最佳实践,即仅使用模式匹配来获取值(例如,因为您经常想要模式匹配其他东西,这加强了一致性)。有时这表明程序员不理解它是如何工作的,并认为它强制完全无法访问 val。
我看到一些像这样的 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
是一个数据class,我们不应该使用private
字段.对于这种情况,我认为正常的 class 就足够了:
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
因为对于正常的 class,构造函数的字段默认是私有的。
但我不确定是否有任何充分的理由在第一种方法中编写代码。
case classes 中的私有值有点令人惊讶,因为它们并不像您想象的那样私有,如果您认为其他获取该值的方法只是语法糖的话。
特别是,模式匹配将为您提供基础值:
whatever match {
case Team(members) => println("I can see "+members.mkString)
}
并且该值仍然在平等中发挥作用(即使您无法通过名称获取它),并且您可以使用 copy
.
有时 private val
用于强制执行 class 的最佳实践,即仅使用模式匹配来获取值(例如,因为您经常想要模式匹配其他东西,这加强了一致性)。有时这表明程序员不理解它是如何工作的,并认为它强制完全无法访问 val。