【发布时间】:2020-05-01 10:56:55
【问题描述】:
我刚刚意识到 F# 记录是引用类型以及我正在进行多少装箱和拆箱。我有很多这样的小记录:
type InputParam =
| RegionString of string
| RegionFloat of float32
但是如果我尝试使用“Struct”属性对其进行标记,我会收到一个编译器错误,指出“FS3204 如果联合类型有多个案例并且是一个结构,那么联合类型中的所有字段都必须是唯一的名字。” language reference 显示创建这样的结构区分联合:
[<Struct>]
type InputParamStruct =
| RegionString of RegionString: string
| RegionFloat of RegionFloat: float32
x of string 和 x of x: string 有什么区别?字段如何不是唯一的?为什么 F# 不默认为记录结构?
【问题讨论】:
-
请注意,如果您查看第一个 DU 的反编译版本,您会发现问题 - RegionString 和 RegionFloat 最终都作为具有单个属性“Item”的类 - sharplab.io/…
-
另外,作为引用类型应该不导致“装箱和拆箱” - 如果您确实经常装箱,那么您的代码中存在不同的问题。实际上,使这个 DU 成为结构可能会显着降低代码的性能(因为整体大小变得比您要传递的引用大很多)。
-
@ReedCopsey "Item" 只是一个名字。如果您使用 x of x: string 定义 ref 类型,它在功能上是相同的,但将名称“Item”交换为“x”。这怎么不会导致更多的拳击? F# 组合在 ref 类型中包装了很多 val 类型。
-
引用类型保持引用 - 它们不会经常被装箱和拆箱。项目是一个隐藏的名称 - 编译器可以想出一些不同的东西,但没有。
标签: struct f# discriminated-union