Scala中的类型安全的通用案例类更新
发布时间:2020-12-16 18:30:59 所属栏目:安全 来源:网络整理
导读:我正在尝试编写一些跟踪记录更改的代码,并在以后应用它们.在动态语言中,我只需保留List [(String,Any)]对的日志,然后在最终决定提交更改时将这些作为更新应用于原始记录. 我需要能够对更新进行内省,因此更新函数列表不合适. 在Scala中,使用反射这是相当简单
我正在尝试编写一些跟踪记录更改的代码,并在以后应用它们.在动态语言中,我只需保留List [(String,Any)]对的日志,然后在最终决定提交更改时将这些作为更新应用于原始记录.
我需要能够对更新进行内省,因此更新函数列表不合适. 在Scala中,使用反射这是相当简单的,但是我想实现类型安全的版本. 我的第一次尝试是尝试无形.如果我们知道特定类型,这很有效. import shapeless._ import record._ import syntax.singleton._ case class Person(name:String,age:Int) val bob = Person("Bob",31) val gen = LabelledGeneric[Person] val updated = gen.from( gen.to(bob) + ('age ->> 32) ) // Result: Person("Bob",32) 但是,我无法弄清楚如何使这项工作一般. trait Record[T] def update( ??? ):T } 鉴于无形状处理这种方式,我不确定这是否可能? 如果我接受了很多样板文件,作为一个糟糕的版本,我可以按照以下方式做一些事情. object Contact { sealed trait Field[T] case object Name extends Field[String] case object Age extends Field[Int] } // A typeclass would be cleaner,but too verbose for this simple example. case class Contact(...) extends Record[Contact,Contact.Field] { def update[T]( field:Contact.Field[T],value:T ) = field match { case Contact.Name => contact.copy( name = value ) case Contact.Age => contact.copy( age = value ) } } 然而,这不是特别优雅,需要大量的样板.我可能会编写自己的宏来处理这个问题,但这似乎是一个相当普遍的事情 – 有没有办法用Shapeless或类似的宏库来处理它? 解决方法
如何将整个类的实例用作更新?
case class Contact(name: String,age: Int) case class ContactUpdate(name: Option[String] = None,age: Option[Int] = None) object Contact { update(target: Contact,delta: ContactUpdate) = Contact( delta.name.getOrElse(target.name) target.age.getOrElse(delta.age) ) } // also,optionally this: object ContactUpdate { apply(name: String) = ContactUpdate(name = Option(name)) apply(age: Int) = ContactUpdate(age = Option(age)) } 我认为,如果你想要真正的类型安全的解决方案,这是最干净,最可读,也可能是最难实现,因为你不需要处理记录,镜头和单个字段描述符,只需要ContactUpdate (name =“foo”)创建更新,并且updates.map(Contact.update(target,_))按顺序应用它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |