F#和Unity:Set.contains在简单的结构相等性测试中失败

时间:2018-02-04 03:14:08

标签: unity3d f#

我在Unity内部使用F#运行Set.contains时遇到了问题。

(Unity并没有正式支持F#,但他们确实支持包含.DLLs作为插件来提供Scripts可以访问的外部编译代码。这个项目包含Unity内部的FSharp.Core.DLL并且运行良好。这是第一个我已经开始使用这种方法了。)

问题是在某些条件下在Unity下运行时内置的F#结构相等支持似乎失败了。在Unity之外作为控制台应用程序运行时,相同的代码会成功。

我在github上有一个示例项目,其中包含一个Visual Studio解决方案,其中包含演示不一致性所需的所有部分:https://github.com/anticrisis/fsharp-unity-test

这很简单:当构建包含结构类型的Set时,无论是F#4.1 [<Struct>]记录,还是旧样式struct / vals / end类型,Set.contains都应该返回true T:

[<Struct>]
type V3 = {x: int; y: int; z: int} 

let testSet0 = Set.empty<V3>
let testSet1 = testSet0.Add({x = 123; y = 123; z = 123})

// fails under Unity
if testSet1.Contains {x = 0; y = 0; z = 1}
then "FAIL test: testSet1"
else "SUCCESS test: testSet1"

这个Contains调用显然应该返回false,它在Unity之外。但是,它在Unity内部运行时返回true。

幸运的是,有两种主要的解决方法:避免使用Set.contains并使用Set.exists。或者,使用元组而不是结构。这两种方法似乎都避免了导致F#在Unity内失败的任何不一致。

存储库包含README中的更多信息以及更多测试来演示此问题。

1 个答案:

答案 0 :(得分:0)

此意外行为是由Windows版64位Mono中的错误引起的:https://github.com/mono/mono/issues/7177

要获得解决方法,请考虑在您定义的任何[<CustomComparison; CustomEquality>]类型上实施[<Struct>]