web-dev-qa-db-ger.com

Sollte ich den final-Modifikator verwenden, um Case-Klassen zu deklarieren?

Laut scala-wartremover statischem Analyse-Tool muss ich vor jede von mir erstellte Fallklasse "final" setzen: Fehlermeldung besagt "Fallklassen müssen final sein".

Laut Sündenbock (ein anderes statisches Analyse-Tool für Scala) sollte ich das nicht tun (Fehlermeldung: "Redundanter finaler Modifikator für case class")

Wer hat Recht und warum?

50
sscarduzio

Es ist nicht redundant in dem Sinne, dass es Dinge ändert, wenn man es verwendet. Wie zu erwarten ist, können Sie eine endgültige Fallklasse nicht erweitern, eine nicht endgültige jedoch. Warum schlägt wartremover vor, dass Fallklassen endgültig sein sollten? Nun, weil es keine gute Idee ist, sie zu erweitern. Bedenken Sie:

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
// ????

"Ja wirklich?" Bar(1,1) entspricht Bar(1,2)? Das ist unerwartet. Aber warte, es gibt noch mehr:

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) // ???

Eine Kopie von Bar hat den Typ Foo? Kann das richtig sein?

Sicher können wir das beheben, indem wir .equals (Und .hashCode Und .toString Und .unapply Und .copy Und auch überschreiben , möglicherweise .productIterator, .productArity, .productElement usw.) für Bar und Baz. Aber "out of the box", jede Klasse, die eine Case-Klasse erweitert, wäre kaputt.

Dies ist der Grund, warum Sie eine Case-Klasse nicht mehr um eine andere Case-Klasse erweitern können. Dies ist verboten, da ich denke, scala 2.11. Das Erweitern einer Case-Klasse um eine Nicht-Case-Klasse ist weiterhin zulässig, ist jedoch nach Ansicht von wartremover keine wirklich gute Idee.

86
Dima