Вопрос по scala, sealed, traits – Что такое запечатанная черта?

304

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

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

Ваш Ответ

5   ответов
84

a sealed trait is the same as a sealed class ?

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

Or, if not, what are the differences ?

Мут.

When is it a good idea to use a sealed trait (and when not) ?

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

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

sealed abstract class Tree[T : Ordering]

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

sealed trait Tree[T : Ordering]

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

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

& quot; поскольку границы контекста (и границы представления) реализованы с неявными параметрами. & quot; - не могли бы вы уточнить это?
26

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

The sealed modifier applies to class definitions. A sealed class may not be directly inherited, except if the inheriting template is defined in the same source file as the inherited class. However, subclasses of a sealed class can be inherited anywhere.

M. Odersky. The Scala language specification, version 2.8. online, Sept., 2013.

48

ОтЕжедневно-скала блог:

When a trait is "sealed" all of its subclasses are declared within the same file and that makes the set of subclasses finite which allows certain compiler checks.

Почему проголосовали?
@ Джон - я не пробовал, но подозреваю, что уроки. Суть в том, что запечатывание заключается в том, что все определено в пределах одной единицы
Спасибо. С "всеми его подклассами" это значит классы и черты? John Threepwood
@JohnThreepwood: классы, черты и объекты. Большую часть времени в Scala используется термин «класс» используется для обозначения классов, черт и объектов. Только если говорить о конкретных различиях между ними, это означаетonly классы. SLS использует термин «шаблон» относиться как к классам, так и к чертам, но этот термин часто не используется вне SLS, и нет термина, который охватывает все три класса, черты и объекты.
423

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

Они часто используются в качестве альтернативы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

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

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

& # X200C; & # x200C; Кратко:

  • Sealed traits ,can only be extended in the same file
  • List this lets the compiler easily know all possible subtypes
  • Use sealed traits when the number of possibly subtypes is finite and known in advance
  • A way of creating something like enum in Java
  • Help to define algebraic data types (ADTs)

и для более подробной информации Все о запечатанных чертах в Scala

Похожие вопросы