如何在F#中创建作为值类型的Union类型?

编程入门 行业动态 更新时间:2024-10-19 18:23:25
本文介绍了如何在F#中创建作为值类型的Union类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

常规F#区分联合是引用类型.如何在F#中创建一个简单(非递归且仅具有值类型字段)联合类型?

Normal F# Discriminated Unions are reference types. How can I create a simple (non-recursive and with only value-type fields) union type in F# that is a value type?

基于一些互联网搜索,我目前(无效)的尝试如下:

Based on some internet searching my current (non-working) attempt looks as follows:

[<StructLayout(LayoutKind.Explicit)>] type Float = [<DefaultValue>] [<FieldOffset 0>] val mutable Val1 : float [<DefaultValue>] [<FieldOffset 0>] val mutable Int1 : int new (a:float) = {Val1 = a}

以下博客似乎显示了通过C#可以实现的目标

我知道上面的代码不是F#的惯用方法,但我正在尝试优化应用程序一部分的性能,并且性能分析清楚地表明,堆分配的成本(JIT_new)是导致性能下降的原因瓶颈...简单的联合类型是满足我需要的理想数据结构,而不仅仅是分配的堆.

I'm aware that the above is NOT idiomatic use of F# but I am trying to optimize the performance of a portion of my application and profiling has clearly shown that the cost of heap allocations (JIT_new) is what is causing my performance bottleneck... A simple union type is the perfect data structure for my needs, just not a heap allocated one.

推荐答案

首先,除非有很好的理由,否则我可能不会这样做.在大多数情况下,结构和引用类型之间的差异实际上并没有那么大-根据我的经验,仅当它们具有非常大的数组时才有意义(然后结构允许您分配一个大的内存块).

First of all, I would probably not do this, unless I had very good reasons. In most cases, the difference between structs and reference types is not really that big - in my experience, it only matters when you have a very large array of them (then structs let you allocate one big memory chunk).

也就是说,看起来F#不喜欢示例中的构造函数代码.我真的不确定为什么(它似乎正在做一些检查,但对于重叠的结构却不太有效),但是以下方法可以解决问题:

That said, it looks like F# does not like the constructor code in your example. I'm really not sure why (it seems to be doing some check that does not quite work for overlapping structs), but the following does the trick:

[<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,具体取决于您的结构所代表的情况.然后,您可以使用主动模式在其上进行模式匹配,并获得一些可区分的并集安全性:

If I actually wanted to use this, I would add another field Tag containing 1 or 0 depending on which case your struct represents. Then you could pattern match on it using an active pattern and get some of the safety of discriminated unions back:

let (|Float|Int|) (s:MyStruct) = if s.Tag = 0 then Float(s.Val1) else Int(s.Int1)

更多推荐

如何在F#中创建作为值类型的Union类型?

本文发布于:2023-11-10 02:37:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1574102.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类型   如何在   Union

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!