作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
普通 F# 可区分联合是引用类型。如何在作为值类型的 F# 中创建一个简单(非递归且仅具有值类型字段)联合类型?
基于一些互联网搜索,我当前(无法正常工作)的尝试如下所示:
[<StructLayout(LayoutKind.Explicit)>]
type Float =
[<DefaultValue>] [<FieldOffset 0>] val mutable Val1 : float
[<DefaultValue>] [<FieldOffset 0>] val mutable Int1 : int
new (a:float) = {Val1 = a}
The following blog post appears to show what is possible via C#
我知道以上不是 F# 的惯用用法,但我正在尝试优化我的应用程序的一部分的性能,并且分析清楚地表明堆分配 (JIT_new) 的成本是导致我的性能的原因瓶颈...一个简单的联合类型是满足我需求的完美数据结构,而不是堆分配类型。
最佳答案
首先,我可能不会这样做,除非我有非常充分的理由。在大多数情况下,结构和引用类型之间的区别并没有那么大——根据我的经验,只有当你有一个非常大的数组时它才重要(然后结构让你分配一个大内存块)。
也就是说,看起来 F# 不喜欢您示例中的构造函数代码。我真的不确定为什么(它似乎正在做一些对重叠结构不太有效的检查),但以下是诀窍:
[<Struct; StructLayout(LayoutKind.Explicit)>]
type MyStruct =
[<DefaultValue; FieldOffset 0>]
val mutable Val1 : float
[<DefaultValue; FieldOffset 0>]
val mutable Int1 : int
static member Int(a:int) = MyStruct(Int1=a)
static member Float(f:float) = MyStruct(Val1=f)
如果我真的想使用它,我会添加另一个包含 1
或 0
的字段 Tag
,具体取决于您的结构代表的情况。然后,您可以使用事件模式对其进行模式匹配,并恢复受歧视联合的一些安全性:
let (|Float|Int|) (s:MyStruct) =
if s.Tag = 0 then Float(s.Val1) else Int(s.Int1)
关于c# - 如何在 F# 中创建值类型的联合类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31405194/
我是一名优秀的程序员,十分优秀!