我有一个特征,它会覆盖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)
。
答案 0 :(得分:1)
我不喜欢这样,我不会这样做,但这是这样:
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
}
}
答案 1 :(得分:1)
使用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))
}