Что такое запечатанная черта?

Запечатанные классы описаны в разделе "Программирование в Scala", но опечатанные черты - нет. Где я могу найти дополнительную информацию о запечатанном признаке?

Я хотел бы знать, если запечатанная черта совпадает с запечатанным классом? Или, если нет, каковы различия? Когда это хорошая идея использовать запечатанную черту (а когда нет)?

Ответ 1

A sealed признак может быть расширен только в том же файле, что и его объявление.

Они часто используются для обеспечения альтернативы enums. Поскольку они могут быть расширены только в одном файле, компилятор знает все возможные подтипы и может рассуждать об этом.

Например, с объявлением:

sealed trait Answer
case object Yes extends Answer
case object No extends Answer

Компилятор выдаст предупреждение, если совпадение не является исчерпывающим:

scala> val x: Answer = Yes
x: Answer = Yes

scala> x match {
     |   case No => println("No")
     | }
<console>:12: warning: match is not exhaustive!
missing combination            Yes

Таким образом, вы должны использовать закрытые черты (или замкнутый абстрактный класс), если количество возможных подтипов конечно и известно заранее. Для получения дополнительных примеров вы можете взглянуть на list и option.

Ответ 2

Запечатанный признак совпадает с запечатанным классом?

Что касается sealed, да. Разумеется, они разделяют нормальные различия между trait и class.

Или, если нет, каковы различия?

Мут.

Когда это хорошая идея использовать запечатанный признак (а когда нет)?

Если у вас есть sealed class X, вам необходимо проверить X, а также любые подклассы. То же самое не относится к sealed abstract class X или sealed trait X. Таким образом, вы можете сделать sealed abstract class X, но тем более более подробным, чем просто trait и для небольшого преимущества.

Основным преимуществом использования abstract class над a trait является то, что он может принимать параметры. Это преимущество особенно важно при использовании классов типов. Скажем, вы хотите, например, построить отсортированное дерево. Вы можете написать это:

sealed abstract class Tree[T : Ordering]

но вы не можете этого сделать:

sealed trait Tree[T : Ordering]

поскольку границы контекста (и границы обзора) реализуются с неявными параметрами. Учитывая, что черты не могут получать параметры, вы не можете этого сделать.

Лично я предпочитаю sealed trait и использую его, если только по какой-то определенной причине я не использую sealed abstract class. И я не говорю о тонких причинах, но по-вашему-причинам вы не можете игнорировать, например, используя классы типов.

Ответ 3

Из ежедневного scala блога:

Когда черта "запечатана", все ее подклассы объявляются в пределах тот же файл и делает набор подклассов конечным, что позволяет некоторые проверки компилятора.

Ответ 4

Также я считаю необходимым указать вам спецификации:

Модификация с печатью применяется к определениям классов. Класс с печатью не может быть непосредственно унаследован, за исключением случаев, когда наследующий шаблон определяется в том же источнике файл как унаследованный класс. Однако подклассы закрытого класса могут быть унаследованы где угодно.

- M. Одерски. Спецификация языка Scala, версия 2.8. онлайн, сентябрь, 2013 г.

Ответ 5

Кратко:

  • Запечатанные черты могут быть расширены только в одном файле
  • Список это позволяет компилятору легко узнать все возможные подтипы
  • Используйте запечатанные черты, когда число возможных подтипов конечно и известно заранее
  • Способ создания чего-то вроде enum в Java
  • Помогите определить алгебраические типы данных (ADT)

и более подробно все о запечатанных чертах в Scala