2011-12-02 41 views
9

Tôi đã thử đoạn code dưới đây (phương pháp bình đẳng được viết sau khi Programming in Scala cuốn sách)Làm thế nào để phù hợp với mô hình một lớp lồng nhau trong 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 

Sau khi một số phân tích tôi thấy rằng Scala định nghĩa lại lớp Room cho mỗi trường hợp của Person và đó là lý do hai phòng aren không bằng nhau.

Một khả năng để giải quyết vấn đề là đặt lớp học bên ngoài lớp học Person, nhưng điều này không phải lúc nào cũng dễ dàng nhất. (Ví dụ: nếu lớp học phải truy cập một số thông số của Person.)

Có phương án nào để viết phương thức tương đương?

Trả lời

15

Vấn đề là hai phòng của bạn là trường hợp của một loại đường phụ thuộc vào: loại của họ là p1.Roomp2.Room:

scala> :type p1.room 
p1.Room 

Một cách để làm cho công việc này là để tham khảo Room sử dụng lựa chọn loại, tức là là 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 
Các vấn đề liên quan