Scala中为何同一文件可存在名称不同的case class与object?
关于Scala伴生对象判定的明确结论
你之前掌握的伴生对象规则没有任何错误,不需要对既有概念产生怀疑。
你看到的示例代码的实际情况
你贴的WikipediaRanking.scala里的两个声明,本来就不是要构建伴生关系,只是同文件下互相独立的两个顶层类型:
- Scala 没有任何规则要求同一个
.scala文件里只能存在一个类、一个object,你可以在一个文件里定义任意多个名称不冲突的顶层特质、类、case类、单例object、通用函数,没有强制配对要求 - 伴生对象的构成条件是刚性的,两个必要条件缺一不可:
- 类(含case类)/特质的名称,和object的名称完全逐字符一致,包括大小写
- 二者必须处于完全相同的源码作用域下——一般日常开发中就是指同一个文件的顶层包声明下,不存在被嵌套到不同的类、不同的包结构里的情况
- 你看到的这个文件的组织方式是Scala项目非常普遍的实践:把作为业务逻辑入口的
WikipediaRankingobject作为文件主命名,把和这个排名逻辑强绑定的辅助数据模型WikipediaArticlecase class也放在同一个文件里,避免为了简单的数据结构单独创建新文件造成冗余。两个名称完全不同的类型,不存在任何伴生关系。
新手常见认知误区纠正
很多刚接触Scala的开发者会误以为"只要在同一个文件里的class和object就是伴生",这是完全错误的:
- 名称不匹配的两个同文件声明,只是普通的同文件类型,不具备伴生对象的特殊能力——比如无法直接访问对方的私有成员、不支持伴生类之间的隐式搜索域关联
- 真正满足伴生关系的写法可以参考下面的示例,这才是符合规则的伴生结构:
// 文件名建议和顶层主类型保持一致,这里就是WikipediaArticle.scala case class WikipediaArticle(title: String, text: String) // 同名同作用域的object,和上面的case class构成伴生 object WikipediaArticle { // 伴生对象可以直接访问case class的私有构造/成员,外部独立object没有这个权限 def createEmptyArticle(title: String): WikipediaArticle = WikipediaArticle(title, "") }
内容的提问来源于stack exchange,提问作者Shengxin Huang
相关产品推荐
相关产品推荐

