我遇到了几个地方在线,其中的代码看起来是这样的:在GetHashCode()中使用F#的散列函数evil?
[<CustomEquality;NoComparison>]
type Test =
| Foo
| Bar
override x.Equals y =
match y with
| :? Test as y' ->
match y' with
| Foo -> false
| Bar -> true // silly, I know, but not the question here
| _ -> failwith "error" // don't do this at home
override x.GetHashCode() = hash x
但是当我运行上面的FSI,当我要么调用hash foo
上的Test
实例或当我提示不回直接致电foo.GetHashCode()
。
let foo = Test.Foo;;
hash foo;; // no returning to the console until Ctrl-break
foo.GetHashCode();; // no return
我不能容易地证明,但它表明hash x
呼叫GetHashCode()
的对象,这意味着上面的代码是危险上。还是只是FSI玩?
我想像上面的代码只是意味着“请实现自定义相等,但保留散列函数默认”。
我有同时实现这种模式不同,但我仍然想知道我是否正确假设hash
只是调用GetHashCode()
,导致一个永恒的循环。
顺便说一句,利用内幕FSI平等立即返回,这表明它要么不比较之前
更新:这是有道理的,因为在上面的例子中GetHashCode()
打电话,或者它别的东西。
x.Equals
不会调用GetHashCode()
,并且等于运算符调用Equals
,而不是调用GetHashCode()
。
_“会在你手动散列一些对象的成员时”_,是的,这实际上是以创建一个可比较的函数类型开始的,类似于string *('T - >'U)',在散列覆盖我在字符串上调用了'hash s'(所以,在那里没有无限递归)。但是当我在网上看到这些线索时,我想,嘿,让我们试试看......引发这个问题。 – Abel
感谢您指向源代码的指针。关于你对例外的评论:你是对的,不好的例子代码......我在鬼混。 – Abel
@Abel是的,我想你可能已经知道了这一点,但我认为值得在其他人看待这个问题/答案的地方出现,因为这是那些很容易做出的常见小错误之一。 – TheInnerLight