2011-12-02 12 views
9

He intentado por debajo del código (el método de la igualdad se escribe después Programming in Scala libro)¿Cómo hacer coincidir patrones con una clase anidada en Scala?

class Person() { 
    class Room(r: Int, c: Int) { 
     val row = r 
     val col = c 

     override def hashCode: Int = 
      41 * (
       41 + row.hashCode 
      ) + col.hashCode 

     override def equals(other: Any) = 
      other match { 
       case that: Room => 
        (that canEqual this) && 
        this.row == that.row && 
        this.col == that.col 
       case _ => false 
      } 

     def canEqual(other: Any) = 
      other.isInstanceOf[Room] 
    } 

    val room = new Room(2,1) 
} 

val p1 = new Person() 
val p2 = new Person() 

println(p1.room == p2.room) 
>>> false 

Después de un análisis descubrí que Scala redefine la clase Room para cada instancia de Person y esa es la razón de las dos habitaciones aren no es igual

Una posibilidad para resolver el problema es colocar la clase fuera de la clase Person, pero esto no siempre es lo más fácil. (Por ejemplo, si la clase tiene que acceder a algunos parámetros de Person.)

¿Qué alternativas hay para escribir el método igual?

Respuesta

15

El problema es que sus dos habitaciones son instancias de un tipo dependiente de la trayectoria: sus tipos son p1.Room y p2.Room:

scala> :type p1.room 
p1.Room 

Una manera de hacer este trabajo es hacer referencia a Room mediante la selección del tipo, es decir, como Person#Room.

class Person() { 
    class Room(r: Int, c: Int) { 
     val row = r 
     val col = c 

     override def hashCode: Int = // omitted for brevity 

     override def equals(other: Any) = 
      other match { 
       case that: Person#Room => 
        (that canEqual this) && 
        this.row == that.row && 
        this.col == that.col 
       case _ => false 
      } 

     def canEqual(other: Any) = 
      other.isInstanceOf[Person#Room] 
    } 

    val room: Room = new Room(2,1) 
} 

val p1 = new Person() 
val p2 = new Person() 

scala> p1.room == p2.room 
res1: Boolean = true 
Cuestiones relacionadas