封印された特性とは何ですか?


332

封印されたクラスは「Scalaでのプログラミング」で説明されていますが、封印された特性は記述されていません。封印された特性に関する詳細情報はどこで入手できますか?

封印された特性が封印されたクラスと同じかどうか知りたいのですが?または、そうでない場合、違いは何ですか?いつ封印された特性を使用するのが良いのですか(そうでない場合)?

回答:


473

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

したがって、可能なサブタイプの数が有限で事前にわかっている場合は、シールドされた特性(またはシールドされた抽象クラス)を使用する必要があります。その他の例については、リストオプションの実装を確認できます。


113
ここにランダムに到着し、ScalaでJava Enumを置き換える方法を理解するのに6か月かかりました。
sscarduzio 2014年

1
非常に素晴らしい !また、有限で事前に既知であるだけでなく、yesのようなすべての可能なサブタイプをチェックするのに意味のある制限された(密封された)コンテキストの一部でもあります。いいえ、さえ| 奇数など...
マリオデサベラ

90

封印された特性は封印されたクラスと同じですか?

限りでsealedは、はい。もちろん、traitとの通常の違いを共有していclassます。

または、そうでない場合、違いは何ですか?

Moot。

いつ封印された特性を使用するのが良いですか(そうでない場合)?

あなたが持っているならsealed class X、あなたはチェックする必要がありますXサブクラスと同様。同じことはsealed abstract class Xまたはには当てはまりませんsealed trait X。だから、あなたはそうすることができますがsealed abstract class X、それは単なるtrait利点よりもはるかに冗長です。

を使用する主な利点 abstract classovertraitパラメーターを受け取ることができることです。この利点は、型クラスを使用する場合に特に関係があります。たとえば、ソートされたツリーを作成するとします。あなたはこれを書くことができます:

sealed abstract class Tree[T : Ordering]

しかし、これを行うことはできません:

sealed trait Tree[T : Ordering]

なぜなら、コンテキストの境界(およびビューの境界)は暗黙的なパラメーターを使用して実装されているからです。トレイトはパラメータを受け取ることができないので、それを行うことはできません。

個人的には、sealed trait特別な理由でを使用しない限り、私はそれを好み、使用しsealed abstract classます。そして、私は微妙な理由について話しているわけではありませんが、型クラスの使用など、あなたが無視できない直接的な理由について話しているのです。


「コンテキストの境界(およびビューの境界)は暗黙的なパラメーターで実装されているため。」-それについて詳しく説明してもらえますか?
Ruby

@Ruby –かなり遅い返信ですが、あなたまたは他の誰かが興味がある場合:コンテキスト境界([A: F])は、分散制約と同じように機能しません。むしろ、暗黙のF[A]スコープを要求するのは構文糖です。これは通常、暗黙的なパラメータ((implicit fa: F[A]))よりも少し簡潔で読みやすい方法でタイプクラスインスタンスを呼び出すために使用されますが、内部的にはまったく同じように機能しますが、Danielが指摘するように、特性は実行できませんそれ。
mirichan

54

毎日、Scalaのブログ

トレイトが「封印」されると、そのすべてのサブクラスが同じファイル内で宣言され、特定のコンパイラチェックを可能にするサブクラスのセットが有限になります。


ありがとうございました。「そのすべてのサブクラス」では、クラスと特性を意味しますか?
ジョンスリープウッド

@ジョン-私は試していませんが、クラスを疑っています。シーリングに関する要点は、すべてがその1つのソースユニット内で定義されるということです
Brian Agnew

1
@JohnThreepwood:クラス、特性、オブジェクト。ほとんどの場合、Scalaでは、「クラス」という用語は、クラス、特性、およびオブジェクトを指すために使用されます。それらの間の特定の違いについて話すときだけ、それはクラスだけを意味します。SLSは「テンプレート」という用語を使用してクラスと特性の両方を指しますが、その用語はSLS以外ではあまり使用されておらず、クラス、特性、およびオブジェクトの3つすべてを網羅する用語はありません。
イェルクWミッターク

30

また、仕様を示す必要性も感じています。

密封された MODI FiのERはFi回線nitions・デ・クラスに適用されます。密封されたクラスを直接継承テンプレートを継承クラスと同じソースファイル内に定義さドFiがある場合を除いて、継承されなくてもよいです。ただし、シールクラスのサブクラスはどこにでも継承できます。

M.オデルスキー。Scala言語仕様、バージョン2.8。オンライン、2013年9月。


7

‌‌簡単:

  • 封印された特性は同じファイルでのみ拡張できます
  • これをリストすると、コンパイラーはすべての可能なサブタイプを簡単に知ることができます
  • 可能性のあるサブタイプの数が有限で事前にわかっている場合は、封印された特性を使用します
  • Javaで列挙型のようなものを作成する方法
  • 代数的データ型(ADT)の定義に役立つ

詳細については、Scalaのシールドされた特性に関する すべて

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.