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
Поэтому вы должны использовать запечатанные черты (или запечатанный абстрактный класс), если число возможных подтипов конечно и известно заранее. Для большего количества примеров вы можете взглянуть на список и реализации опций .
Что касается
sealed
, да. Они разделяют обычные различия междуtrait
иclass
, конечно.Мут.
Если у вас есть
sealed class X
, то вы должны проверить,X
а также любые подклассы. То же самое не относится кsealed abstract class X
илиsealed trait X
. Так что вы могли бы сделатьsealed abstract class X
, но это гораздо более многословно, чем простоtrait
и для небольшого преимущества.Основным преимуществом использования
abstract class
над atrait
является то, что он может получать параметры. Это преимущество особенно актуально при использовании классов типов. Допустим, вы хотите построить отсортированное дерево, например. Вы можете написать это:но вы не можете сделать это:
поскольку границы контекста (и границы представления) реализованы с неявными параметрами. Учитывая, что черты не могут получать параметры, вы не можете этого сделать.
Лично я предпочитаю
sealed trait
и использую это, если какая-то конкретная причина не заставляет меня использоватьsealed abstract class
. И я говорю не о тонких причинах, а о личных причинах, которые вы не можете игнорировать, таких как использование классов типов.источник
[A: F]
) не работает так же, как ограничения на дисперсию. Скорее, это синтаксический сахар, требующий неявногоF[A]
охвата. Обычно он используется для вызова экземпляров классов типов таким способом, который немного сложнее и проще для чтения, чем неявный параметр ((implicit fa: F[A])
), но он все еще работает точно так же, как и Дэниел, и, как указывает Дэниел, черты не могут быть выполнены который.Из блога daily-scala :
источник
Также я чувствую необходимость указать вам спецификации:
источник
Кратко:
и более подробно все о запечатанных чертах в Scala
источник