digitalmars.D.learn - Compare two objects
- Qian Xu (45/45) Feb 10 2009 Hi All,
- grauzone (14/69) Feb 10 2009 It's a shortcoming in the design of the == operator. Code like "a==b"
- Qian Xu (3/5) Feb 10 2009 But you have to write much more, just like my test(..) function does
- Frits van Bommel (17/24) Feb 10 2009 ((a is b) || (a && a == b))
- Frank Benoit (3/3) Feb 10 2009 (a && a == b)
- Frank Benoit (2/5) Feb 10 2009 hm, no :(
Hi All, I want to test, if two objects are equal. The rules are as follows: 1. When both are null, it should return true. 2. When one of them is null, it should return false. 3. When both not null, then compare their values (as two strings) My test code --------------------------------------------------------------- class Test { private int value; this(int value) { this.value = value; } public int getValue() { return this.value; } bool opEquals(Test obj) { if (obj is null) { return this is null; } return this.getValue() == obj.getValue(); } } procedure test(Test a, Test b) { if (a is null && b is null) return true; if (a !is null && a == b) return true; return false; } void main() { Test a; Test b = new Test(100); assert(test(a, b)); // ok assert(a != b); // av error } ---------------------------------------------------------------- If object at the left side of the != is null, I will get an AV error immediately. If I want to compare two objects safely, I have to write my own test(..) function. But this is not nice. Can someone explain, is this a design shortcoming of D-Compiler, or I am wrong. Best regards --Qian Xu
Feb 10 2009
Qian Xu wrote:Hi All, I want to test, if two objects are equal. The rules are as follows: 1. When both are null, it should return true. 2. When one of them is null, it should return false. 3. When both not null, then compare their values (as two strings) My test code --------------------------------------------------------------- class Test { private int value; this(int value) { this.value = value; } public int getValue() { return this.value; } bool opEquals(Test obj) { if (obj is null) { return this is null; } return this.getValue() == obj.getValue(); } } procedure test(Test a, Test b) { if (a is null && b is null) return true; if (a !is null && a == b) return true; return false; } void main() { Test a; Test b = new Test(100); assert(test(a, b)); // ok assert(a != b); // av error } ---------------------------------------------------------------- If object at the left side of the != is null, I will get an AV error immediately. If I want to compare two objects safely, I have to write my own test(..) function. But this is not nice. Can someone explain, is this a design shortcoming of D-Compiler, or I am wrong.It's a shortcoming in the design of the == operator. Code like "a==b" will always be compiled to this:a.opEquals(b)If a is null, the call will always cause a segfault. You simply can't call a method on a null object. There are two reasons for this: 1. it will dereference the object's vtable to look up virtual methods and 2. the runtime will try to call the object's invariant, which segfaults too. (Actually, I see an assert with a null check in _d_invariant(). But somehow, gdb usually still shows a segfault in _d_invariant(). Maybe Phobos isn't compiled in debug mode.) The D compiler even has a special rule to disallow compilation of code like "a==null" (yes, because of the null literal). It seems Walter added this, because people were using this code to check if an object is null. Conclusion: == is absolutely useless in your case. Use something else.Best regards --Qian Xu
Feb 10 2009
grauzone wrote:Conclusion: == is absolutely useless in your case. Use something else.But you have to write much more, just like my test(..) function does --Qian Xu
Feb 10 2009
Qian Xu wrote:Hi All, I want to test, if two objects are equal. The rules are as follows: 1. When both are null, it should return true. 2. When one of them is null, it should return false. 3. When both not null, then compare their values (as two strings)((a is b) || (a && a == b)) Note that if a and b are both the same non-null object, opEquals will not be called; it'll just evaluate to true. It's not very nice-looking, but it's the best you can do. Of course, you could put it into a function: ----- bool equals(T)(T a, T b) { return ((a is b) || (a && a == b)); } ----- Note that this may behave strangely for empty arrays: ----- char[] str; equals(str, ""); // returns false ----- But of course, that's what you asked for. 'str' is null and "" isn't...
Feb 10 2009
(a && a == b) is sufficient for his use case. Because he wants the way with the least amount of typing.
Feb 10 2009
Frank Benoit schrieb:(a && a == b) is sufficient for his use case. Because he wants the way with the least amount of typing.hm, no :(
Feb 10 2009