是否可以通过 F# 创建第三方可变结构 "more immutable"?

Is it possible to make a third-party mutable struct "more immutable" via F#?

例如,不会是这样的类型:

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

... 有 public 个像这样的可变字段:

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

...单枪匹马地使使用 F# 代码的不可变性努力变得毫无用处?

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

PPS:我做了一些研究并怀疑答案(否定),但希望能提供一些意见。如果不从头开始在 F# 中实现所有内容,这似乎是一个典型的问题。

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

var vecB = Vector2.Normalize(vecA);

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

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

对于 structs 的集合,这不是问题。无论结构的成员如何,集合都保持不变,因为从集合 returns 中获取结构的副本。更改此副本不会更改集合的内容。

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

作为旁注,我不建议使用来自 F# 外部的向量 类,因为它们不支持度量单位。根据我的经验,大多数向量都可以分配物理单位,这使代码更安全、更易读。