是否有可能制作第三方可变结构"更不可变的结构#34;通过F#?

时间:2015-01-28 17:40:23

标签: c# f# immutability mutable

例如,不会是这种类型:

https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.aspx

......拥有像这样的公共可变字段:

https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.x.aspx

......一手消费F#代码的不变性努力有点无用吗?

PS:必须保留性能,不要包装或动态实例化丢弃值。

PPS:我做了一些研究并怀疑答案(否定),但会欣赏一些意见。当没有从头开始实现F#中的所有内容时,这似乎是一个典型的问题。

2 个答案:

答案 0 :(得分:3)

你是对的,简短的回答是否定的。但是,至少在您展示的Vector2类的情况下,当您使用方法的静态版本时,许多操作都以不可变的方式实现。例如

var vecB = Vector2.Normalize(vecA);

是一个不可变的电话。除非您使用的库支持某种不变性,否则您将不得不实现您想要的不可变功能。

F#的设计目标是将可变内容和不可变内容混合在一起,以便在需要时可以访问.NET库的丰富功能。

答案 1 :(得分:3)

对于structs的集合,这不是问题。无论struct的成员如何,该集合都是不可变的,因为从集合中获取结构会返回一个副本。更改此副本不会改变集合的内容。

在其他地方,结构可用于编写包装器而无需额外的GC负载。这需要为要保留的所有要素创建方法,并让它们调用原始方法。除非JIT没有内联电话,否则这不应该是性价比。但是,在包装引用类型时,这将在包装器类型上创建一个空的默认构造函数,如果调用此构造函数,则会产生空引用。

作为旁注,我不推荐使用F#外部的矢量类,因为它们不是测量单位。根据我的经验,大多数向量都可以分配物理单位,这使代码更安全,更易读。