简体   繁体   English

在“案例类”中具有“私有”构造函数字段有意义吗?

[英]Does it make sense to have a `private` constructor field in a `case class`?

I see some Scala code like this: 我看到一些这样的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)
}

You can see the Team is a case class , but it has a private field members . 您可以看到Team是一个case class ,但是它有一个private领域的members And in the body, it has several methods to construct a new Team , and a method allNames which export some information of the private members . 并且在主体中,它有几种方法来构造一个新的Team ,以及一个allNames方法来导出一些私有members

I'm not sure if the usage of case class is good, since I think a case class is a data class, we should not use private fields. 我不确定case class的用法是否合适,因为我认为case class是数据类,所以我们不应该使用private字段。 For this case, I think a normal class is enough: 对于这种情况,我认为普通班就足够了:

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)
}

You can see I removed the case , and also private since for a normal class, the fields of constructor is private by default. 您可以看到我删除了case ,也删除了private因为对于普通的类,构造函数的字段默认为private。

But I'm not sure if there is any good reason to write the code in the first approache. 但是我不确定是否有充分的理由在第一种方法中编写代码。

Private vals in case classes are a little surprising because they're not as private as you might imagine if you think other ways of getting that value are just syntactic sugar. 案例类中的私有val有点令人惊讶,因为如果您认为获得价值的其他方法只是语法糖,它们就不会像您想象的那样私有。

In particular, pattern matching will give you the underlying value: 特别是,模式匹配将为您提供基础价值:

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

And the value still plays a role in equality (even if you can't get it by name), and you can create copies with different values using copy . 而且值仍然在平等中起作用(即使您无法通过名称获取它),并且可以使用copy创建具有不同值的copy

Sometimes a private val is used to enforce best practices for that class, which is to only use pattern matching to get the values (eg because you will often want to pattern match other things, and this enforces consistency). 有时,使用private val强制执行该类的最佳实践,即仅使用模式匹配来获取值(例如,因为您经常想对其他事物进行模式匹配,因此会增强一致性)。 Sometimes it's an indication that the programmer doesn't understand how it works and thinks its enforcing a complete lack of access to the val. 有时,这表明程序员不了解其工作方式,并认为其强制完全缺乏对val的访问权。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM