2011-12-02 11 views
9

Ho provato il codice qui sotto (il metodo uguale viene scritto dopo Programming in Scala libro)Come associare pattern a una classe nidificata in 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 

Dopo un po 'di analisi ho scoperto che Scala ridefinisce la classe Room per ogni istanza di Person e questa è la ragione per le due camere aren sono uguali

Una possibilità per risolvere il problema è mettere la classe al di fuori della classe Person, ma questo non è sempre il più semplice. (Ad esempio se la classe deve accedere ad alcuni parametri di Person.)

Quali alternative ci sono per scrivere il metodo uguale?

risposta

15

Il problema è che i vostri due camere sono istanze di un tipo dipendente dal percorso: i loro tipi sono p1.Room e p2.Room:

scala> :type p1.room 
p1.Room 

Un modo per fare questo lavoro è quello di fare riferimento a Room tramite selezione del tipo, vale a dire come 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 
Problemi correlati