封印されたクラスは 'Programming in Scala'で説明されていますが、封印された特性はそうではありません。封印された特性に関する詳細な情報はどこにありますか?
封印された特性が封印されたクラスと同じであれば、私は知りたいですか?そうでない場合、違いは何ですか?封印された特性を使用するのが良い場合がありますか(そうでない場合)。
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 の実装を見てください。
封印された特性は封印されたクラスと同じですか?
sealed
に関する限り、そうです。もちろん、それらはtrait
とclass
の通常の違いを共有します。
そうでない場合、違いは何ですか?
おたふく。
封印された特性を使用するのが良い場合がありますか(そうでない場合)。
あなたがsealed class X
を持っているなら、あなたはX
と同様にあらゆるサブクラスをチェックしなければなりません。 sealed abstract class X
やsealed trait X
についても同じことは言えません。 sealed abstract class X
を実行することもできますが、それは単なるtrait
よりも冗長であり、ほとんど利点がありません。
trait
よりabstract class
を使用する主な利点は、パラメータを受け取ることができるということです。この利点は、型クラスを使用するときに特に関係があります。たとえば、ソートツリーを構築したいとしましょう。あなたはこれを書くことができます:
sealed abstract class Tree[T : Ordering]
しかし、これはできません。
sealed trait Tree[T : Ordering]
コンテキストの境界(およびビューの境界)は暗黙のパラメータで実装されているからです。特性がパラメータを受け取れないことを考えると、それはできません。
個人的には、私はsealed trait
を好み、特別な理由でsealed abstract class
を使わない限りそれを使います。微妙な理由については話していませんが、タイプクラスを使用するなど、無視できないような理由があります。
daily-scalaブログ から:
特性が「封印」されると、そのすべてのサブクラスが同じファイル内で宣言され、それによってサブクラスのセットが有限になり、特定のコンパイラチェックが可能になります。
また、私はあなたが仕様を示す必要があると感じます:
シール修飾子はクラス定義に適用されます。継承テンプレートが継承クラスと同じソースファイルで定義されている場合を除き、シールクラスは直接継承できません。ただし、シールされたクラスのサブクラスはどこにでも継承できます。
簡単に言えば:
そして詳細については Scalaの封印された特性に関するすべて