Scala listing and reflection

After a lot of work in Java, I became interested in Scala. As a training project, I am trying to duplicate a java library that stores and retrieves state objects from a database. To do this, I would simply indicate the state object as follows:

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

The code to serialize / un -serialize an instance of Person uses reflection to know the types of fields and works fine for everyone except the gender field. The gender field is an enumeration that is defined as:

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

The problem is that I don’t know how I can use reflection, I also create a new Gender value using only the Person class.

+3
source share
4 answers

Scala , case :

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

, match, Scala , , . , , .: -)

+4

Gender.Male.id, . 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 "" .

Enumeration, .

0

, . , .

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 scala.Enumeration field
val typ:Type = ... object scala.Enumeration field 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)

unit test, .

. : , , scala Enumeration?

0

Source: https://habr.com/ru/post/1714075/


All Articles