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

269

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

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

Теги:
traits
sealed

4 ответа

345

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.

  • 98
    Мне потребовалось шесть месяцев, чтобы случайно прибыть сюда и понять, как заменить Java Enum в Scala.
  • 0
    очень хорошо ! и не только конечный и известный заранее, но также и часть ограниченного (закрытого?) контекста, где имеет смысл проверить все возможные подтипы, такие как да | нет, даже | странный и т.д ...
74

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

Что касается 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. И я не говорю о тонких причинах, но по-вашему-причинам вы не можете игнорировать, например, используя классы типов.

  • 0
    «поскольку границы контекста (и границы представления) реализованы с неявными параметрами». - не могли бы вы уточнить это?
42

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

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

  • 0
    Спасибо. «Все его подклассы» означают классы и черты?
  • 1
    Почему проголосовали?
Показать ещё 2 комментария
20

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню