我不知道其中的F#的原因拳击情况下平等的测试,以及是否有其压倒一切的情况下,Equals与GetHashCode和实施IEquatable<>是优于使用StructuralEqualityAttribute.如果是这样,是否可以在不降低=运营商绩效的情况下完成?
对于包含一个整数的简单结构,我运行了一个循环,重复相同的等式检查1M次.我用循环定时...
= 与自定义(类型和值测试)相等:约110ms= 结构平等:20ms至25ms==重定向到IEquatable的自定义运算符:1ms到3ms==直接比较值的自定义运算符:0ms(由优化程序擦除)根据我的理解,IEquatable<>界面可以用作性能优化,以在检查相等性时防止装箱.这似乎在C#中很常见,但我很难在F#中找到它.此外,F#编译器在尝试覆盖=给定类型的运算符时会抱怨.
该StructuralEquality属性记录在MSDN中以仅覆盖Equals和GetHashCode.但是,它确实阻止了显式实现IEquatable<>.但是,生成的类型与之不兼容IEquatable<MyType>.如果结构上等同的类型没有实现,这对我来说似乎不合逻辑IEquatable<>?
关于=F#规范(3.0规范中的8.15.6.2)的性能有一个注释,但我不知道该怎么做:
注意:在实践中,为所有基类型的直接调用(=),比较和散列发出快速(但语义上等效)的代码,并且使用更快的路径来比较大多数数组
之前给出的"基类型"的定义对于阅读本说明似乎没有用.这是指基本类型吗?
我糊涂了.到底是怎么回事?如果类型可以用作集合键或频繁的相等测试,那么正确的等式实现会是什么样的?
我遇到了RequireQualifiedAccess的问题:尽管有这个属性,但是一个联合案例正在影响一个类型.奇怪的是,如果我在封闭模块上使用合格访问权限,而不是在封闭模块内部或我打开它,则只会出现错误:
module Module =
type [<RequireQualifiedAccess>] Du =
| SomeCase
type [<RequireQualifiedAccess>] SuperDu =
| Du of Du
let valid = Du.SomeCase // Valid, as expected
let invalid = Module.Du.SomeCase // Not defined?!?
open Module
let validToo = Du.SomeCase // Wait, this is valid again?
Run Code Online (Sandbox Code Playgroud)
在无效行中,首先出现一个警告,即.Du不使用限定访问权限,不推荐使用,就像我所指的那样SuperDu.Du,然后它会给出一个SomeCase未定义的错误.
我一直认为,使用open X等同于X.从该模块中获取的所有定义的前缀.但它显然不是......?
这里发生了什么?尽管如此,我是否必须避免这种名称冲突RequireQualifiedAccess?这是编译器错误吗?
当使用带有度量单位类型参数的自定义类型时,我遇到了编译器错误"本地调用的类型参数数量不正确",我不明白为什么.
这个问题经历了不少编辑.现在看来错误是由编译器或IDE错误引起的.
我可以将其缩小到以下内容(在尝试重现时阅读以下几点):
type R<[<Measure>] 'u> (f : float<'u>) =
member r.Member = f
let get (r : R<_>) = r.Member
let foo =
let problem _ = List.map get
problem // Error: Incorrect number of type arguments to local call
Run Code Online (Sandbox Code Playgroud)
最后一行给出了错误,这是特别奇怪的,因为它只是返回已经定义的标识符.我正在编译库或可执行文件.一些重要的复制观察:
IntelliSense 无法预测此错误.需要进行实际编译才能看到它.
在使用优化进行编译时,我还没有看到错误.(对于复制,请使用例如Visual Studio中的默认调试编译.感谢Freenode上的zapu指出这一点.)
我还没有看到F#interactive中的错误.
删除problem(the _)的无用参数会使错误消失.
移动let-binding of problemout foo会使错误消失.这可能与编译作为F#函数有关吗?我听说这是通过围绕类型的附加括号表示的 problem.
删除度量单位使用会使错误消失.
标记problem为inline使错误消失.
许多看似无关紧要的更改消除了错误.但在实际使用案例中并不容易,特别是在我尝试之前我不知道更改是否修复了错误.
我对这方面的任何暗示感到高兴.是什么导致的?这是一个错误,如果是这样,它是否已知?怎么可以避免?
版本使用F#3.0到3.1.2的版本进行了测试.我安装了新的Visual Studio 2013社区版,并使用它提供的版本进行了测试,结果相同.它也出现在Visual Studio 2012(F#3.0)中. …
当运算符的一侧具有已知类型而另一侧不具有已知类型时,某些函数用法不会编译.一个例子是计量单位:
let inline multiplyWithFive x = 5. * x
type [<Measure>] myUnit
let test = multiplyWithFive 3.<myUnit> // Compiler error
Run Code Online (Sandbox Code Playgroud)
5. * 3.<myUnit>显然是一个有效的表达式,所以这是令人惊讶的,特别是考虑到inline函数在其他情况下最大化:
let inline multiply a b = a * b
let test = multiply 5. 3.<myUnit> // Valid
Run Code Online (Sandbox Code Playgroud)
但是,这不仅限于计量单位.比方说,我做了一个支持浮点数不对称乘法的类型.它与multiplyWithFive函数不兼容,函数任意推断其参数为float:
type BoxFloat =
{ Value : float }
static member inline (*) (lhs : float, rhs : BoxFloat) =
{ Value = lhs * rhs.Value }
let boxThree = { Value = …Run Code Online (Sandbox Code Playgroud)