Scala Реализация Reflection для поиска имени пользователя - PullRequest
0 голосов
/ 24 января 2020

Если у меня есть ситуация с классом дела, подобная этой:

case class ColorId(id: Int) 

С объектом-компаньоном, который выглядит следующим образом:

/**
  * Contains all possible colors that can be applied.
  */
object ColorId {
  val RED = ColorId(1)
  val GREEN = ColorId(2)
  val BLUE = ColorId(3)
  val WHITE = ColorId(4)
  val BLACK = ColorId(5)
  val UNKNOWN = ColorId(6)
}

val blue = ColorId.BLUE

assert(blue.getNameString == "BLUE")

Конечно, есть способ использовать отражение, чтобы получить утверждение быть правдой. Как должна выглядеть реализация метода getNameString объекта ColorId?

РЕДАКТИРОВАТЬ: Нет необходимости указывать метод c. Например, допустимо что-то вроде blue.getClass.getXXX.getName.

РЕДАКТИРОВАТЬ # 2: Удаление этой сопоставимой части.

Ответы [ 2 ]

2 голосов
/ 24 января 2020

Попробуйте

case class ColorId(id: Int)

object ColorId {
  val RED = ColorId(1)
  val GREEN = ColorId(2)
  val BLUE = ColorId(3)
  val WHITE = ColorId(4)
  val BLACK = ColorId(5)
  val UNKNOWN = ColorId(6)
}

object UnsafeColorIdMap {
  lazy val nameById: Map[Int, String] = {
    scala.reflect.runtime.currentMirror
      .classSymbol(ColorId.getClass)
      .info
      .members
      .filter(_.isMethod)
      .map(_.name.toString)
      .filter(_.forall(Character.isUpperCase))
      .toList
      .reverse
      .zip(LazyList from 1)
      .toMap
      .map(_.swap)
  }
}

final implicit class UnsafeColorToNameString(private val c: ColorId) extends AnyVal {
  def unsafeGetNameString: String = UnsafeColorIdMap.nameById(c.id)
}

assert(ColorId.BLUE.unsafeGetNameString == "BLUE")

, однако обратите внимание на префикс небезопасный .

1 голос
/ 24 января 2020

Я предлагал использовать простую Карту , чтобы получить название цвета с учетом id.

Примерно так:

object ColorId {
  val RED = ColorId(1)
  val GREEN = ColorId(2)
  val BLUE = ColorId(3)
  val WHITE = ColorId(4)
  val BLACK = ColorId(5)
  val UNKNOWN = ColorId(6)

  def getName(color: ColorId): String = color.id match {
    case 1 => "RED"
    case 2 => "GREEN"
    case 3 => "BLUE"
    case 4 => "WHITE"
    case 5 => "BLACK"
    case 6 => "UNKNOWN"
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...