2009-07-31 7 views
3

Javaで長年働いた後、私はScalaに興味を持ち始めました。 学習プロジェクトとして、私はデータベースから状態オブジェクトを格納し、取得するJavaライブラリを複製しようとしています。このため 、私はちょうどこのような状態のオブジェクトを指定できるようにしたいと思います。人の/アンシリアライズインスタンスをシリアル化するスカラの列挙と反映

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

コードは、フィールドの種類を知るためにリフレクションを使用してのための[OK]を動作しますジェンダーの分野を除くすべて問題は、私はあまりにものみPersonクラスを使用して、新しい性別値を作成するリフレクションを使用することができる方法がわからないということです

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

: 性別フィールドは、次のように定義された列挙です。

+0

なぜ「のみPersonクラスを使用して」:

また、私はここでこの答えのバージョンを展開する参照してください? – Blaisorblade

答えて

4

Scalaの列挙は面白いですが、ケースクラスが頻繁にそれ以上のエッジを持っている:

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

これができmatchであるという利点を持っている、とあなたが他の一方の性のテストではなく、場合スカラ座にも文句を言うでしょう。そして、あなたの問題をより簡単に解くようです。 :-)

0

Gender.Male.idを使用すると、男性の性別値のIntプレゼンテーションを取得できます。 Gender.apply()を使用し、それを取り戻すします

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 

あなたが永続化ビットを処理しているために、すべてを行う必要がシリアライズ時に性別ののInt表現を格納し、デシリアライズ時に性別に戻って、それを復元することです。

解決策を一般化する場合は、[列挙型]フィールドでカスタム注釈を使用します。

0

私は同じ問題に遭遇し、ややかさばる解決策を見つけましたが、それは機能します。リフレクションを使用してValueから実際のEnumerationを見つける方法がないので、Enumerationを囲むEnumerationの名前を保持する必要があります。

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 

今、あなたは、データベースから読み出した

// 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) 
0

EnumReflectorをチェックアウト:

あなたはそれをフィールドのScalaのタイプを指定する必要があります。

val enumObject:Type = ... object's scala.Enumeration field 
val typ:Type = ... object's scala.Enumeration field's scala type 

val isEnum = EnumReflector.isEnumeration(typ) 

val reflector = EnumReflector(typ) 
val eid = reflector.toID(enumObject) 
val enum = reflector.fromID(eid) 
assertTrue(eid eq enum) 

プロジェクトには、それを実証する単体テストがあります。 Is it possible to use reflection to find the actual type of a field declared to be a Scala Enumeration subtype?

関連する問題