2011-12-02 12 views
9

私は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 

いくつかの分析の後、私はScalaはPersonの各インスタンスのクラスRoomを再定義し、その2つの部屋が上がらない理由だことがわかった(同じメソッドがProgramming in Scala書物後に書かれている)以下のコードを試してみました同じだ。

問題を解決する可能性は、クラスPersonの外部にクラスを配置することですが、これは常に最も簡単な方法ではありません。 (例えば、クラスがPersonのいくつかのパラメータにアクセスしなければならない場合)

等価メソッドを書くための代替手段はありますか?

答えて

15

問題は、あなたの二つの部屋がパス依存型のインスタンスであるということです。その種類はp1.Roomp2.Room次のとおりです。この作品を作るために

scala> :type p1.room 
p1.Room 

一つの方法は、タイプの選択を使用してRoomを参照することで、すなわち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 
関連する問題