を区別列挙型は、私はちょうど非会員は、労働組合を区別宣言で少しだけ違いがあることに気づいた組合
type Color =
| Red = 0
| Green = 1
| Blue = 2
を何パフォーマンス、使用法などの主な違いは何ですか?あなたは何を使うべきかについての示唆を持っていますか?
を区別列挙型は、私はちょうど非会員は、労働組合を区別宣言で少しだけ違いがあることに気づいた組合
type Color =
| Red = 0
| Green = 1
| Blue = 2
を何パフォーマンス、使用法などの主な違いは何ですか?あなたは何を使うべきかについての示唆を持っていますか?
列挙型は列挙されているため、スタック上に割り当てられます。一方、識別された共用体は参照型であり、ヒープが割り当てられます。だから、実際にはこの違いに気付くことはほとんどありませんが、DUの方が列挙型のパフォーマンスがやや劣ると思います。
さらに重要なことに、識別された共用体は宣言された型の1つにしかなりません。enumは本当に単なる整数なので、列挙型のメンバーではない整数を列挙型にキャストできます。これは、DUのすべてのケースをカバーしたときにパターンマッチングが完了したことをコンパイラがアサートすることができるが、enumの場合は常にすべての残りのケースをキャッチする必要があることを意味します。
match enumColor with
| Red -> 1
| Green -> 2
| Blue -> 3
| _ -> failwith "not an enum member"
ここで、最後のケースはDUでは必要ないでしょう。
C#とVB.NETの両方で列挙型がネイティブにサポートされているため、DUはそうではありませんでした。他の言語で使用するパブリックAPIを作成するときには、
ロバートによると、ユニオンのパターンマッチングは2つの方法のいずれかで行われます。 null値のケースのみを持つ共用体(関連する値がない場合)(これは列挙型に非常に一致します)では、コンパイラによって生成されたTag
プロパティがチェックされます。これはint
です。この場合、パフォーマンスはenumと同じになると期待できます。 non-nullaryのケースを持つ共用体の場合は、タイプテストが使用されますが、これはかなり高速です。ロバートが言ったように、パフォーマンスの差異がある場合は無視できます。しかし、前者の場合、それはまったく同じでなければなりません。
enumの固有の「不完全性」に関して、パターンマッチが失敗したときに、本当に知りたいのは、有効なケースがマッチでカバーされていない場合です。無効な整数値が列挙型にキャストされたかどうかは一般的に気にしません。その場合、試合は失敗します。私はほとんどいつも組合を好みますが、(通常は相互運用性のために)列挙型を使用する必要があるとき、義務的なワイルドカードのケースでは、一致しない値をa function that distinguishes between valid and invalid valuesに渡し、適切なエラーを発生させます。
F#4.1より、struct discriminated unionsがあります。
これらは列挙型のようなスタック割り当てのパフォーマンス上の利点があります。
これらは、識別されたユニオンの一致が優れています。
これらはF#固有なので、他の.Net言語でも理解できるようにするにはenumを使用する必要があります。