Scala: классы соответствия - PullRequest
       10

Scala: классы соответствия

8 голосов
/ 20 октября 2011

Следующий код утверждает, что Джек работает в строительстве, но Джейн является еще одной жертвой грубой экономики:

abstract class Person(name: String) {

  case class Student(name: String, major: String) extends Person(name)

  override def toString(): String = this match {
    case Student(name, major) => name + " studies " + major
    case Worker(name, occupation) => name + " does " + occupation
    case _ => name + " is unemployed"
  }
}

case class Worker(name: String, job: String) extends Person(name)

object Narrator extends Person("Jake") {
  def main(args: Array[String]) {
    var friend: Person = new Student("Jane", "biology")
    println("My friend " + friend) //outputs "Jane is unemployed"
    friend = new Worker("Jack", "construction")
    println("My friend " + friend) //outputs "Jack does construction"
  }
}

Почему матч не может распознать Джейн как ученицу?

Ответы [ 2 ]

5 голосов
/ 20 октября 2011

Я считаю, что здесь происходит то, что класс Student объявляется внутри Person.Следовательно, case Student в toString будет соответствовать только Student s, которые являются частью конкретного Person экземпляра.

Если вы переместите case class Student параллельно case class Worker (и затем удалите ненужные extends Person("Jake") из object Narrator ..., которые есть только там, чтобы new Student оказался Person$Student специфичным для Джейка), вы обнаружите, что Джейн действительно изучает биологию.

4 голосов
/ 20 октября 2011

Эмиль совершенно прав, но вот пример, чтобы прояснить это:

scala> case class A(a: String) {
     |   case class B(b: String)
     |   def who(obj: Any) = obj match {
     |     case B(b) => println("I'm A("+a+").B("+b+").")
     |     case b: A#B => println("I'm B("+b+") from some A")
     |     case other => println("Who am I?")
     |   }
     | }
defined class A

scala> val a1 = A("a1")
a1: A = A(a1)

scala> val a2 = A("a2")
a2: A = A(a2)

scala> val b1= a1.B("b1")
b1: a1.B = B(b1)

scala> val b2 = a2.B("b2")
b2: a2.B = B(b2)

scala> a1 who b1
I'm A(a1).B(b1).

scala> a1 who b2
I'm B(B(b2)) from some A

Точнее, эта строка:

case Student(name, major) => name + " studies " + major

действительно означает

case this.Student(name, major) => name + " studies " + major

К сожалению, в то время как Джейн была создана на Джейке, this в случае Джейн указывает на саму Джейн.

...