2011-10-19 9 views
8

El siguiente código afirma que Jack se emplea en la construcción, pero Jane es una víctima más de la economía áspera:Scala: Coincidencia de clases de casos

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" 
    } 
} 

¿Por qué el partido no reconocen Jane como estudiante?

Respuesta

4

Emil es del todo correcto, pero aquí hay un ejemplo para que quede claro:

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 

Para ser más precisos, esta línea:

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

significa realmente

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

Desafortunadamente , mientras que Jane fue instanciada en Jake, this en el caso de Jane apunta a la propia Jane .

5

Lo que creo que está sucediendo aquí es que la clase de caso Student se está declarando dentro de Person. Por lo tanto, el case Student en el toString solo coincidirá con Student s que forman parte de una instancia particular de Person.

Si mueve el case class Student a ser paralela a la case class Worker (y luego eliminar lo innecesario de extends Person("Jake")object Narrator ... que sólo está ahí para que la new Student terminó siendo un Person$Student específica a Jake), se encuentra Jane hace de hecho, estudie biología.

+0

¿Puedes aclarar a qué te refieres con "una instancia de Persona en particular"? – divider

+0

¿Alguien sabe si este comportamiento está documentado en alguna parte? –

+0

@divider: 'friend' es un' Narrator.Person', pero no un 'friend.Person'. –

Cuestiones relacionadas