Scala复制和反射



在我的项目中,有很多地方的对象是从集合中挑选出来的,在更改了一些值的情况下进行复制,然后推回到集合中。我一直在尝试创建自己的"复制"方法,除了进行复制外,还为我提供了一个"Diff"对象。换句话说,包含你刚刚放入其中的论点的东西。

然后应该将"Diff"对象发送到某个地方进行聚合,这样其他人就可以获得自上次以来的所有更改的报告,而无需发送实际的整个对象。如果一个人这样做,这一切都很简单:

val user = new User(Some(23), true, "arne", None, None, "position", List(), "email", None, false)
val user0 = user.copy(position = "position2")
list ::= user0
val diff =  new Diff[User](Map("position" -> "position2"))

然而,那里有一些重复的工作,我非常希望只使用一种方法,比如:

val (user, diff) = user.copyAndDiff(position = "position")

我还没能弄清楚"复制"的参数实际采用的形式,但我也可以使用其他形式。

我做了一个带有Type参数的方法,它应该是一个副本和一个diff

object DiffCopy[Copyable]{
  def apply(original:Copyable, changes:Map[String, Any]){
    original.copy(??uhm..
    original.getAllTheFieldsAndCopyAndOverWriteSomeAccordingToChanges??

我的第一个问题是,似乎没有任何方法可以保证原始对象有一个可以重载的"复制"方法。当我想在新的复制对象中实际将更改分配给它们的正确字段时,就会出现第二个问题。我试着摆弄Reflection,并试图找到一种方法来设置名称为String的字段的值。在这种情况下,我可以将Diff作为一个简单的映射,只需首先创建这个Diff映射,然后将其应用于我的对象,并将它们发送到需要的地方。

然而,我最终在兔子洞里越陷越深,离我真正想要的越来越远。我得到了一个点,我有一个来自任意对象的字段数组,可以按名称获取它们,但我无法使它适用于泛型类型。所以现在我在这里问是否有人能就这种情况给我一些建议?

我能得到的最好的答案是,如果有人能告诉我一个简单的方法,将Map[String,Any]应用于等效于"复制"方法的东西。我很确定这应该可以实现,但目前我还无法实现…

有点过于复杂,但可以解决最初的问题。

我能得到的最好的答案是,如果有人能告诉我一个简单的方法,将Map[String,Any]应用于等效于"复制"方法的东西。我很确定这应该是可能实现的,但它只是目前超出了我的能力…

  1. 将case类中的所有字段都映射到映射中。

  2. 使用新值更新地图。

  3. 从新字段映射创建案例类。

问题:

  • 低性能

我确信它可以做得更简单。。。

 case class     Person(name: String, age: Int)
  def getCCParams(cc: Any) =
    (Map[String, Any]() /: cc.getClass.getDeclaredFields) {(a, f) =>
      f.setAccessible(true)
      a + (f.getName -> f.get(cc))
    }
  def enrichCaseClass[T](cc: T, vals : Map[String, Any])(implicit cmf : ClassManifest[T]) = {
    val ctor = cmf.erasure.getConstructors().head
    val params = getCCParams(cc.asInstanceOf[Any]) ++ vals
    val args = cmf.erasure.getDeclaredFields().map( f => params(f.getName).asInstanceOf[Object] )
    ctor.newInstance(args : _*).asInstanceOf[T]
  }
  val j = Person("Jack", 15)
  enrichCaseClass(j, Map("age" -> 18))

相关内容

  • 没有找到相关文章

最新更新