scala-wartremover 静的解析ツールによると、作成するすべてのケースクラスの前に「final」を配置する必要があります。エラーメッセージは「ケースクラスはfinalでなければならない」と言います。
scapegoat (Scalaの別の静的解析ツール)によると、代わりにすべきではありません(エラーメッセージ:「ケースクラスの冗長な最終修飾子」)
誰が正しいのですか?
それを使用すると物事が変わるという意味で冗長ではありません。予想どおり、最終ケースクラスを拡張することはできませんが、非最終クラスを拡張することはできます。なぜwartremoverは、ケースクラスが最終的なものであることを示唆していますかなぜなら、それらを拡張するのはあまり良い考えではないからです。このことを考慮:
_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)
?と等しいこれは予想外です。しかし、待って、もっとあります:
_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
?ですか?これは正しいのでしょうか?
確かに、_.equals
_(および_.hashCode
_、および_.toString
_、および_.unapply
_、および_.copy
_をオーバーライドすることでこれを修正できます。また、おそらく_.productIterator
_、_.productArity
_、_.productElement
_など)Bar
およびBaz
のメソッド。しかし、「箱から出して」、ケースクラスを拡張するクラスはすべて壊れます。
これが、別のケースクラスによってケースクラスを拡張することができなくなったため、scala 2.11。ケース以外のクラスによってケースクラスを拡張することはまだ考えられているため、禁止されています。許可されていますが、少なくとも、ウォートレーバーの意見では、あまり良い考えではありません。