我在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中的更多信息以及更多测试来演示此问题。
答案 0 :(得分:0)
此意外行为是由Windows版64位Mono中的错误引起的:https://github.com/mono/mono/issues/7177。
要获得解决方法,请考虑在您定义的任何[<CustomComparison; CustomEquality>]
类型上实施[<Struct>]
。