den*_*e99 6 hash d equals object
看看我正在构建的这个简单类,它是存储字符串匹配算法结果的基础:
/** Match of a single pattern in full to a single text. */
class Match {
uint Tpos;
this(in uint Tpos) { this.Tpos = Tpos; }
override string toString() {
return text("Match: Text@",Tpos);
}
}
Run Code Online (Sandbox Code Playgroud)
事情变得奇怪:
auto m1 = new Match(1), m2 = new Match(1);
writeln(m1.toHash());
writeln(m2.toHash());
writeln(m1 == m2);
Run Code Online (Sandbox Code Playgroud)
版画
4464528
4464512
false
Run Code Online (Sandbox Code Playgroud)
我认为没有理由为什么这两个对象默认不应该被认为是相等的.我想我可以写一个自定义toHash()和opEquals()函数,但这似乎有点矫枉过正.据安德烈Alexandrescu的的书在d编程语言(伟大的书!),"默认情况下,散列通过使用对象的按位表示来计算." 有什么想法吗?
你必须自己实施toHash,因为Object.toHash取决于地址.如果我没记错的话,那只是一个return cast(hash_t)cast(void*)this.
编辑:是的,我没记错:https://github.com/D-Programming-Language/druntime/blob/master/src/object_.d#L88
从源代码(dmd2/src/druntime/src/object_.d):
class Object
{
/* snip */
/**
* Compute hash function for Object.
*/
hash_t toHash() @trusted nothrow
{
// BUG: this prevents a compacting GC from working, needs to be fixed
return cast(hash_t)cast(void*)this;
}
/* snip */
/**
* Returns !=0 if this object does have the same contents as obj.
*/
equals_t opEquals(Object o)
{
return this is o;
}
}
Run Code Online (Sandbox Code Playgroud)
所以答案很简单就是编写代码的方式 - 他们进行身份检查而不是内容检查.为什么会这样?我真的不知道,但我的猜测是原来写起来很简单并且工作得很好,以至于没有人愿意回到它并改变它.
在新闻组中,有一些关于完全从Object中删除这些函数的讨论,所以如果你想在你的类上使用==,你将不得不实现一些东西.但是,当涉及到这样的事情时,新闻组谈话成为行动所需的时间通常很长.他们可能会改变主意.
目前和可能在可预见的未来使用类相等的最佳方法是在类中编写自己的opEquals方法.