4

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
}

Person のインスタンスをシリアル化/非シリアル化するコードは、リフレクションを使用してフィールドのタイプを認識し、性別フィールド以外のすべてに対して正常に機能します。性別フィールドは、次のように定義された列挙型です。

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

問題は、リフレクションを使用して Person クラスのみを使用して新しい Gender 値を作成する方法がわからないことです。

4

4 に答える 4

4

Scala の Enumeration は興味深いものですが、ケース クラスはしばしばそれよりも優れています。

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

これにはできるという利点がありmatch、一方の性別をテストしてもう一方の性別をテストしない場合、Scala は文句を言うことさえあります。そして、それはあなたの問題をより簡単に解決するようです. :-)

于 2009-07-31T16:34:13.930 に答える
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表現を格納し、逆シリアル化するときに性別に復元するだけです。

ソリューションを一般化する場合は、列挙型フィールドにカスタム注釈を使用します。

于 2009-08-03T09:45:38.383 に答える
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 find the actual type of a field defined to be a Scala Enumeration subtype?

于 2016-05-11T15:57:39.547 に答える
0

I have run into the same problem and found a rather bulky solution but it works. You need to persist the name of the enclosing Enumeration since there is no way to find out the real Enumeration from a Value using reflection.

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

Now when you read out from the database

// 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)
于 2012-07-20T21:22:07.757 に答える