首页 > 解决方案 > 按名称激活惰性变量

问题描述

假设我有一个带有惰性成员的案例类

case class Person(name: String, surname: String) {
  lazy val initials: String = name(0) + "." + surname(0) + "."
}

我有一个通用函数可以将其转换为 Map

def getCCParams(cc: AnyRef) =
  cc.getClass.getDeclaredFields.map { f =>
    f.setAccessible(true)
    f.getName -> f.get(cc)
  }.toMap

现在我创造了一个人并获得了它的价值观

val JohnSmith = Person("John", "Smith")
val res = getCCParams(JohnSmith)
println(res)

因此我得到了结果

HashMap(initials -> null, name -> John, surname -> Smith)

首字母等于 null 因为它没有被调用。有什么方法可以激活getCCParams函数内部的惰性值?我可以作为参数传递的惰性成员列表

def getCCParams(cc: AnyRef, lazyMembers: List[String] = List("initials")) = ...

谢谢

标签: scalareflectionlazy-evaluation

解决方案


第一次调用访问器方法时会初始化惰性 val。所以也许你可以直接调用这些方法而不是直接进入字段?

def getCCParams(cc: AnyRef) = {
  val clazz = cc.getClass
  clazz.getDeclaredFields.flatMap { f =>
    Try(clazz.getMethod(f.getName)) //get the accessor method by name of field
      .toOption
      .map(m => f.getName -> m.invoke(cc))
  }.toMap
}

结果: Map(initials -> J.S., name -> John, surname -> Smith)


推荐阅读