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