2012-08-23 22 views
6

Echa un vistazo a este sencillo clase Estoy construyendo como la base para almacenar los resultados de los algoritmos de coincidencia de cadenas:¿Por qué estos objetos no son iguales por defecto en D?

/** 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: [email protected]",Tpos); 
    } 
} 

Aquí es donde las cosas se ponen raras:

auto m1 = new Match(1), m2 = new Match(1); 
writeln(m1.toHash()); 
writeln(m2.toHash()); 
writeln(m1 == m2); 

impresiones

4464528 
4464512 
false 

No veo ninguna razón por la cual estos dos objetos no se consideren iguales por defecto. Supongo que podría escribir una función personalizada toHash() y opEquals(), pero eso parece exagerado. De acuerdo con Andrei Alexandrescu book en el lenguaje de programación D (gran libro!), "Por defecto, el hash se calcula utilizando la representación bit a bit del objeto". ¿Alguna idea por ahí?

Respuesta

8

A partir del código fuente (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; 
    } 
} 

Así que la respuesta es simplemente que es la forma en que se escribe el código: hacen una verificación de identidad en lugar de una verificación de contenido. ¿Por qué es así? Realmente no lo sé, pero creo que fue simple escribir originalmente y funciona lo suficientemente bien como para que nadie se haya tomado la molestia de volver y cambiarlo.

En el grupo de noticias, se ha debatido la posibilidad de eliminar por completo estas funciones de Object, por lo que si quiere == en sus clases, tendrá que implementar algo. Pero el tiempo que toma la charla de los grupos de noticias para convertirse en acción cuando se trata de cosas como esta suele ser bastante largo. Y podrían cambiar sus mentes.

La mejor forma de usar la igualdad de clases actualmente y probablemente en un futuro previsible es escribir su propio método opEquals en la clase.

+0

Gracias por el código fuente y la información. No me di cuenta == comparado por identidad por defecto. Terminé reescribiéndolo como una estructura de todos modos, ya que querré copiar el objeto por valor la mayor parte del tiempo. – denine99

4

La respuesta es simple: por defecto, opEquals para objetos compara las direcciones de los objetos. Usted debe anularlo si quiere semántica de valores (o simplemente usar un struct).

Nota al margen: el uso de in es incorrecto. in es la abreviatura de scope const donde scope significa "No escaparé de este parámetro fuera de mi marco de pila" (lo cual se hace asignándolo a un campo de clase). Lamentablemente, el compilador aún no hace cumplir esto, por lo que no obtuvo un error.

+2

No estoy seguro, pero creo que el alcance se refiere a las referencias (o indicadores) de escape y que es legal copiar los argumentos de valor puro con ámbito a las variables externas. – cybevnm

+3

'scope' (y por lo tanto' in') en los parámetros de funciones se supone que evita que las referencias asociadas con ese argumento escapen de la función (lo que incluiría su asignación a una variable miembro) - aunque es verdad que las verificaciones _no están implementadas correctamente ahora mismo. Sin embargo, en este caso particular, está bien independientemente, porque el parámetro es un 'uint', que es un tipo de valor. 'scope' no tiene un significado real para los tipos de valor, solo los tipos de referencia, porque el argumento se copia y, por lo tanto, no hay ninguna referencia para escaparse. –

+0

Supongo que 'in' no es el mejor modificador aquí; 'const' es una mejor opción, aunque con un constructor tan corto probablemente no importa qué calificadores se usen. Gracias por la información sobre 'scope'. – denine99

Cuestiones relacionadas