枚举与非成员歧视工会

发布于 2025-01-02 11:20:35 字数 244 浏览 1 评论 0原文

只有一点点区别

type Color =
    | Red
    | Green
    | Blue

我刚刚注意到声明非成员歧视联合体和声明枚举

type Color =
    | Red = 0 
    | Green = 1
    | Blue = 2

:它们在性能、用法等方面的主要区别是什么?您有什么建议何时使用什么?

I've just noticed that there's only a little difference in declaring a non-member discriminated union:

type Color =
    | Red
    | Green
    | Blue

and declaring an enum:

type Color =
    | Red = 0 
    | Green = 1
    | Blue = 2

What are their main differences in terms of performance, usage, etc? Do you have suggestions when to use what?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千紇 2025-01-09 11:20:35

枚举是结构,因此在堆栈上分配,而可区分联合是引用类型,因此在堆上分配。因此,您可能会期望 DU 的性能略低于枚举,尽管实际上您可能永远不会注意到这种差异。

更重要的是,可区分联合只能是声明的类型之一,因为枚举实际上只是一个整数,因此您可以将不是枚举成员的整数转换为枚举类型。这意味着,当模式匹配时,当您覆盖了 DU 的所有情况时,编译器可以断言模式匹配已完成,但对于枚举,您必须始终放入默认捕获所有其余情况,即对于枚举,您总是需要模式匹配,例如:

match enumColor with
| Red -> 1 
| Green -> 2
| Blue -> 3
| _ -> failwith "not an enum member"

最后一种情况对于 DU 来说是不必要的。

最后一点,由于 C# 和 VB.NET 都原生支持枚举,而 DU 则不然,因此在创建供其他语言使用的公共 API 时,枚举通常是更好的选择。

Enum are stucts and are therefore allocated on the stack, while discriminated unions are references types so are heap allocated. So, you would expect DU to be slightly less performant that enums, though in reality you'll probably never notice this difference.

More importantly a discriminated union can only ever be one of the types declared, where as enums are really just an integer, so you could cast an integer that isn't a member of the enum to the enum type. This means that when pattern matching the compiler can assert that the pattern matching is complete when you've covered all the cases for a DU, but for an enum you must always put in a default catch all the rest case, i.e for an enum you'll always need pattern matching like:

match enumColor with
| Red -> 1 
| Green -> 2
| Blue -> 3
| _ -> failwith "not an enum member"

where as the last case would not be necessary with an DU.

One final point, as enums are natively supported in both C# and VB.NET, were as DUs are not, enums are often a better choice when creating a public API for consumption by other languages.

握住我的手 2025-01-09 11:20:35

除了罗伯特所说的之外,联合上的模式匹配是通过两种方式之一完成的。对于仅具有空值情况的联合,即没有关联值的情况(这与枚举密切相关),将检查编译器生成的 Tag 属性,该属性是一个 int。在这种情况下,您可以预期性能与枚举相同。对于具有非空情况的联合,使用类型测试,我认为这也相当快。正如罗伯特所说,如果存在性能差异,则可以忽略不计。但在前一种情况下,它应该完全相同。

关于枚举固有的“不完整性”,当模式匹配失败时,您真正想知道的是匹配是否未涵盖有效的情况。您通常不关心是否将无效的整数值转换为枚举。在这种情况下,您希望比赛失败。我几乎总是更喜欢联合,但是当我必须使用枚举(通常是为了互操作性)时,在强制通配符的情况下,我将不匹配的值传递给 区分有效值和无效值并引发适当错误的函数。

In addition to what Robert has said, pattern matching on unions is done in one of two ways. For unions with only nullary cases, i.e., cases without an associated value (this corresponds closely to enums), the compiler-generated Tag property is checked, which is an int. In this case you can expect performance to be the same as with enums. For unions having non-nullary cases, a type test is used, which I assume is also pretty fast. As Robert said, if there is a performance discrepancy it's negligible. But in the former case it should be exactly the same.

Regarding the inherent "incompleteness" of enums, when a pattern match fails what you really want to know is if a valid case wasn't covered by the match. You don't generally care if an invalid integer value was casted to the enum. In that case you want the match to fail. I almost always prefer unions, but when I have to use enums (usually for interoperability), inside the obligatory wildcard case I pass the unmatched value to a function that distinguishes between valid and invalid values and raises the appropriate error.

不奢求什么 2025-01-09 11:20:35

从 F# 4.1 开始,有 构造有区别的联合

它们具有堆栈分配的性能优势,例如枚举。

他们拥有受歧视工会的优越匹配。

它们是 F# 特定的,因此如果您需要被其他 .Net 语言理解,您仍然应该使用枚举。

As of F# 4.1 there are struct discriminated unions.

These have the performance benefits of stack allocation, like enums.

They have the superior matching of discriminated unions.

They are F# specific so if you need to be understood by other .Net languages you should still use enums.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文