2009-07-31 7 views
3

Nachdem ich lange in Java gearbeitet habe, begann ich mich für Scala zu interessieren. Als Lernprojekt versuche ich, eine Java-Bibliothek zu duplizieren, die Statusobjekte aus der Datenbank speichert und abruft. Dafür möchte Ich mag Lage sein, nur einen Zustand angeben Objekt wie folgt:Scala Aufzählung und Reflexion

@PersistName("PERSON") case class Person extends Entity { 
    @Persist var id:Long = -1 
    @Persist @MaxLength(80) var firstName = "" 
    @Persist @MaxLength(80) var lastName = "" 
    @Persist var gender = Gender.Male 
    @Persist @MaxLength(80) var userName = "" 
    @Persist @OptionClass(classOf[Date]) var birthDay:Option[Date] = None 
} 

Der Code/un-Serialisierung serialisiert eine Instanz von Person Reflexion verwendet die Feldtypen kennen und arbeitet ok für alles außer dem Geschlechtsfeld. Die Gender-Bereich ist eine Aufzählung, die definiert ist als:

object Gender extends Enumeration { 
    type Gender = Value 
    val Male,Female,Unknown = Value 
} 

Das Problem ist, dass ich weiß nicht, wie ich Reflektion verwenden kann auch ein neues Geschlecht Wert nur die Person-Klasse zu erstellen.

+0

Warum die „nur die Person-Klasse“? – Blaisorblade

Antwort

4

Scala Enumeration ist interessant, aber Fallklassen häufig einen Vorteil gegenüber sie haben:

sealed class Gender 
case object Male extends Gender 
case object Female extends Gender 

Diese haben den Vorteil, match der Lage zu sein, und Scala wird auch beschweren, wenn Sie für ein Geschlecht testen, aber nicht die andere . Und es scheint Ihr Problem leichter zu lösen. :-)

0

Sie können Gender.Male.id verwenden, um eine Int-Präsentation des männlichen Geschlechtswerts zu erhalten. Verwenden Sie Gender.apply(), um es zurück:

val person = Person() 

println("gender = " + person.gender.id) 
// prints "gender = 0" on my mac 

person.gender = Gender(Gender.Female.id) // have a little operation 
println("gender = " + person.gender.id) 
// prints "gender = 1" on my mac 

Da Sie die Persistenz Bit sind Handling, alles, was Sie tun müssen, ist die Int Darstellung von Geschlecht zu speichern, wenn die Serialisierung und es wieder zurück nach Geschlecht, wenn Deserialisieren.

Verwenden Sie eine benutzerdefinierte Anmerkung in den Feldern Enumeration, wenn Sie die Lösung verallgemeinern möchten.

0

Ich habe das gleiche Problem und eine ziemlich sperrige Lösung gefunden, aber es funktioniert. Sie müssen den Namen der umschließenden Enumeration beibehalten, da es nicht möglich ist, die tatsächliche Enumeration eines Werts mithilfe der Reflektion herauszufinden.

object WeekDay extends Enumeration { 
    type WeekDay = Value 
    val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
} 

val day = WeekDay.Fri 

val className = day.getClass.getField("$outer").get(day).getClass.getCanonicalName 

// write to database 
// className // String 
// day.id // Int 

Nun, wenn Sie lesen aus der Datenbank heraus

// read from database 
// obtain className and id 

// enumObject will be WeekDay 
val enumObject = Class.forName(className).getField("MODULE$").get().asInstanceOf[Enumeration] 

// value will be WeekDay.Fri 
val value = enumObject(id)