在Scala中将case类标记为final有什么实际好处

nuypyhwy  于 8个月前  发布在  Scala
关注(0)|答案(2)|浏览(88)

一些开源库like twitters似乎有一个将case类标记为final的约定。
我的团队正在决定是否采用这种约定,但我们还不知道这样做的好处。目前我能感觉到的唯一可能的好处是它阻止了case类的意外继承。
但是它还有其他的优点吗?它能改善编译时间或者允许编译器增加内部优化吗?
我希望它能帮助检测模式匹配中的缺失值,但它似乎也没有做到这一点。在这样一个简单的脚本中,编译器为matchSealed生成一个警告,但不为matchFinal生成警告:

sealed case class Sealed(one: Option[Int], two: Option[Int])

def matchSealed(s: Sealed): Unit = s match {
  case Sealed(Some(i), None) => println(i)
}

final case class Final(one: Option[Int], two: Option[Int])

def matchFinal(f: Final): Unit = f match {
  case Final(Some(i), None) => println(i)
}

字符串
我对final的印象是,它比sealed有更强的限制,所以奇怪的是,这不会生成警告。

j8ag8udp

j8ag8udp1#

下面是an explanation of some benefits
final case类不能被任何其他类扩展。这意味着你可以对你的代码的行为做出更强的保证。你知道没有人可以子类化你的类,覆盖一些方法,并使一些愚蠢的事情发生。当你调试代码时,这是很好的-你不必在对象层次结构中寻找实际被调用的方法。
当然,将类设为final意味着你失去了某种形式的可扩展性,如果你发现自己确实想让用户实现功能,你应该将该功能 Package 在trait中,并使用type class模式。

zbdgwd5y

zbdgwd5y2#

如果case class嵌套在trait或class中,由于作用域的原因,你会得到不同的行为。没有修饰符,每个case class示例都可以访问封闭的运行时trait/class示例。使用它,这种访问可能会丢失,这取决于是否存在对外部作用域的引用,并且你会得到编译器警告。是否需要路径依赖行为将决定你的选择。

相关问题