在声明案例类时是否应该使用final修饰符? [英] Should I use the final modifier when declaring case classes?

查看:125
本文介绍了在声明案例类时是否应该使用final修饰符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 scala-wartremover 静态分析工具,我必须在我创建的每个案例类的前面加上"final":error消息显示案例类必须是最终的".

According to scala-wartremover static analysis tool I have to put "final" in front of every case classes I create: error message says "case classes must be final".

根据 scapegoat (Scala的另一种静态分析工具),我不应该(错误消息:冗余的最终修饰符位于案例类")

According to scapegoat (another static analysis tool for Scala) instead I shouldn't (error message: "Redundant final modifier on case class")

谁是正确的,为什么?

推荐答案

就使用它确实可以改变事物的意义而言,这不是多余的.正如人们所期望的,您不能扩展最终案例类,但是可以扩展非最终案例类. 为什么wartremover建议案例类应该是最终的?好吧,因为扩展它们并不是一个好主意.考虑一下:

It is not redundant in the sense that using it does change things. As one would expect, you cannot extend a final case class, but you can extend a non-final one. Why does wartremover suggest that case classes should be final? Well, because extending them isn't really a very good idea. Consider this:

scala> case class Foo(v:Int)
defined class Foo

scala> class Bar(v: Int, val x: Int) extends Foo(v)
defined class Bar

scala> new Bar(1, 1) == new Bar(1, 1)
res25: Boolean = true

scala> new Bar(1, 1) == new Bar(1, 2)
res26: Boolean = true
// ????

真的吗? Bar(1,1)等于Bar(1,2)吗?这是出乎意料的.但是,等等,还有:

Really? Bar(1,1) equals Bar(1,2)? This is unexpected. But wait, there is more:

scala> new Bar(1,1) == Foo(1)
res27: Boolean = true

scala> class Baz(v: Int) extends Foo(v)
defined class Baz

scala> new Baz(1) == new Bar(1,1)
res29: Boolean = true //???

scala> println (new Bar(1,1))
Foo(1) // ???

scala> new Bar(1,2).copy()
res49: Foo = Foo(1) // ???

Bar的副本的类型为Foo?这样可以吗?

A copy of Bar has type Foo? Can this be right?

当然,我们可以通过覆盖.equals(和.hashCode.toString.unapply.copy,还有可能是.productIterator.productArity.productElement等).但是开箱即用"的任何扩展案例类的类都将被破坏.

Surely, we can fix this by overriding the .equals (and .hashCode, and .toString, and .unapply, and .copy, and also, possibly, .productIterator, .productArity, .productElement etc.) method on Bar and Baz. But "out of the box", any class that extends a case class would be broken.

这是原因,您不能再将一个案例类扩展到另一个案例类,自从我认为scala 2.11开始就被禁止了.仍然可以将案例类扩展为非案例类,但是至少在Wartremover看来这不是一个好主意.

This is the reason, you can no longer extend a case class by another case class, it has been forbidden since, I think scala 2.11. Extending a case class by a non-case class is still allowed, but, at least, in wartremover's opinion isn't really a good idea.

这篇关于在声明案例类时是否应该使用final修饰符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆