如何在Scala中对嵌套类进行模式匹配?

时间:2011-12-02 11:33:30

标签: scala pattern-matching

我已尝试过以下代码(等同方法是在Programming 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

经过一些分析后,我发现Scala为Room的每个实例重新定义了类Person,这就是两个房间不相等的原因。

解决问题的一种可能性是将课程放在课程Person之外,但这并不总是最简单的。 (例如,如果类必须访问Person的某些参数。)

有什么选择来写同等方法?

1 个答案:

答案 0 :(得分: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