加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

结构化在运行时等于Scala

发布时间:2020-12-16 09:11:05 所属栏目:安全 来源:网络整理
导读:scala中是否有一些功能在运行时结构化比较两个对象?由于字段的数量,我宁可不必手动创建一个equals函数.这是一个单元测试,所以性能不是一个问题.我只需要一些反映在字段中的东西,并比较值. 背景:我有一个case类,从覆盖equals的特征扩展,因此不会生成结构性e
scala中是否有一些功能在运行时结构化比较两个对象?由于字段的数量,我宁可不必手动创建一个equals函数.这是一个单元测试,所以性能不是一个问题.我只需要一些反映在字段中的东西,并比较值.

背景:我有一个case类,从覆盖equals的特征扩展,因此不会生成结构性equals(squeryl KeyedEntity,related:Prevent Mixin overriding equals from breaking case class equality),现在我无法改变.这是一个单元测试,所以这两个实例都不会持久化.

解决方法

我想出了这个解决方案,它遍历所有字段,对于私有字段,在scala中找到一个相应的方法.事实上,案例类可以通过相同名称的方法访问私有成员.

implicit class ReallyEqual[T](a: T) {
  import java.lang.reflect.Modifier._
  def ==:==[U](b: U): Boolean = {
    val fieldsA = a.getClass.getDeclaredFields
    val methodsA = a.getClass.getDeclaredMethods
    val mapA = (methodsA.toList map (z => (z.getName(),z))).toMap
    val fieldsB = b.getClass.getDeclaredFields
    val methodsB = b.getClass.getDeclaredMethods
    val mapB = (methodsB.toList map (z => (z.getName(),z))).toMap
    fieldsA.length == fieldsB.length &&
    (true /: (fieldsA zip fieldsB)){ case (res,(aa,bb)) =>
      if(((aa.getModifiers & STATIC) != 0) || ((bb.getModifiers & STATIC) != 0)) { res  // ignore
      } else if(((aa.getModifiers & (PRIVATE | PROTECTED)) == 0) && ((bb.getModifiers & (PRIVATE | PROTECTED)) == 0)) {
        res && aa == bb && aa.get(a) ==:== bb.get(b)
      } else if((mapA contains aa.getName) && (mapB contains bb.getName)) {
        res && mapA(aa.getName).invoke(a) == mapB(aa.getName).invoke(b)
      } else res
    }
  }
}

trait EqualBad {
  override def equals(other: Any) = false
}

case class MyCaseClass(x: Int,y: List[Int]) extends EqualBad

MyCaseClass(1,List(1,2)) ==:== MyCaseClass(1,2)) // true
MyCaseClass(1,List(2,2)) // false
MyCaseClass(1,2)) ==:== MyCaseClass(2,2)) == MyCaseClass(1,2))  // false

您甚至可以通过将ReallyEqual方法中的最后一个==更改为==:==来进行更多的递归

仔细:这对于整数是无效的,因为Int没有任何字段或方法.例如:1 ==:== 2将返回true.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读