Получение имени поля в виде строки - PullRequest
0 голосов
/ 25 октября 2018

У меня есть черта, которая переопределяет toString для печати значений всех полей:

/**
  * Interface for classes that provide application configuration.
  */
trait Configuration {
  /** abstract fields defined here. e.g., **/
  def dbUrl: String

  /**
    * Returns a list of fields to be excluded by [[toString]]
    */
  protected def toStringExclude: Seq[String]

  /**
    * Returns a String representation of this object that prints the values for all configuration fields.
    */
  override def toString: String = {
    val builder = new StringBuilder
    val fields = this.getClass.getDeclaredFields
    for (f <- fields) {
      if (!toStringExclude.contains(f.getName)) {
        f.setAccessible(true)
        builder.append(s"${f.getName}: ${f.get(this)}\n")
      }
    }
    builder.toString.stripSuffix("\n")
  }
}

Конкретный класс в настоящее время выглядит так:

class BasicConfiguration extends Configuration {
  private val config = ConfigFactory.load

  override val dbUrl: String = config.getString("app.dbUrl")

  /**
    * @inheritdoc
    */
  override protected def toStringExclude: Seq[String] = Seq("config")
}

Проблема в том,если бы config были переименованы в какой-то момент, среда IDE пропустила бы "config" в toStringExclude, поскольку это всего лишь строка.Поэтому я пытаюсь найти способ получить имя поля в виде строки, например getFieldName(config).

Ответы [ 2 ]

0 голосов
/ 25 октября 2018

Использование https://github.com/dwickern/scala-nameof,

import com.github.dwickern.macros.NameOf._

class BasicConfiguration extends Configuration {
  private val config = ConfigFactory.load

  override val dbUrl: String = config.getString("app.dbUrl")

  /**
    * @inheritdoc
    */
  override protected def toStringExclude: Seq[String] = Seq(nameOf(config))
}
0 голосов
/ 25 октября 2018

Мне это не нравится, и я бы этого не делал, но вот это:

class BasicConfiguration extends Configuration {

  private val config = ConfigFactory.load

  override val dbUrl: String = config.getString("app.dbUrl")

  private val excludeFields: Set[Any] = Set(config)

  override protected val toStringExclude: Seq[String] = {
    this.getClass
      .getDeclaredFields
      .filter(field => Try(field.get(this)).fold(_ => false, a => excludeFields.contains(a)))
      .map(_.getName)
      .toList
  }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...