Подтвердить что ты не робот

Должен ли я использовать последний модификатор при объявлении классов классов?

В соответствии с scala -wartremover инструментом статического анализа я должен поставить "final" перед каждым классом классов, который я создаю: сообщение об ошибке говорит: "классы case должны быть окончательным".

В соответствии с scapegoat (еще один инструмент статического анализа для Scala) вместо этого я не должен (сообщение об ошибке: "Резервный окончательный модификатор в классе case" )

Кто прав, и почему?

4b9b3361

Ответ 1

Это не избыточно в том смысле, что использование его действительно меняет вещи. Как и следовало ожидать, вы не можете продлить окончательный класс case, но вы можете расширить неконкретный. Почему 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. Но "из коробки" любой класс, который расширяет класс case, будет разбит.

По этой причине вы больше не можете расширять класс case другим классом case, это было запрещено, так как, я думаю, scala 2.11. Расширение класса case нестандартным классом все еще разрешено, но, по крайней мере, в решении wartremover на самом деле не очень хорошая идея.