【问题标题】:Will the var members in case class affect case class's equality?case 类中的 var 成员会影响 case 类的相等性吗?
【发布时间】:2013-01-15 23:54:44
【问题描述】:

我在我的代码中大量使用案例类,回复案例类的基本相等定义以正确运行。然后现在我发现我需要在一个案例类中添加另一个字段成员。

  1. 那么如果我在case 类中添加var 字段成员,会不会弄乱case 类的相等属性?
  2. 如果 1 是肯定的,那么如果我只更改一次 var 字段值,之后,在 case 类进入任何集合或进行相等比较之前,不会发生任何重新分配,那仍然会搞砸平等行为?

【问题讨论】:

    标签: scala equality case-class algebraic-data-types


    【解决方案1】:

    案例类相等性仅基于其主要构造函数属性,无论它们是var 还是val(是的,您可以通过给出显式的var 来使它们成为var 以覆盖隐含的val这种情况下类构造函数 args 拥有。)在 case class 的主体中添加属性不会影响编译器生成的 equals(other: Any) 方法。

    证人:

    package rrs.scribble
    
    object  CCVarEq
    {
      case class CC1(i: Int, j: Float, var k: Double)
    
      case class CC2(i: Int, j: Float, var k: Double) {
        var l = math.Pi
      }
    
      def show {
        val cc11 = CC1(1, 2.0f, 3.0)
        val cc12 = CC1(1, 2.0f, 3.0)
    
        val cc21 = CC2(1, 2.0f, 3.0); cc21.l = math.E
        val cc22 = CC2(1, 2.0f, 3.0)
    
        printf("cc11 == cc12: %s%n", cc11 == cc12); cc12.k = math.Pi * math.E
        printf("cc11 == cc12: %s%n", cc11 == cc12)
    
        printf("cc21 == cc22: %s%n", cc21 == cc22)
      }
    }
    

    在 REPL 中:

    scala> import rrs.scribble.CCVarEq._
    import rrs.scribble.CCVarEq._
    
    scala> show
    cc11 == cc12: true
    cc11 == cc12: false
    cc21 == cc22: true
    

    jamie 关于并发的所有观点也是有效的。

    【讨论】:

      【解决方案2】:

      事情没那么简单。您在一个线程上更新案例类 var,而另一个线程正在执行相等性检查。除非 var 是 volatile,否则在执行相等性检查之前,对 var 的更改可能不会传播到其他线程。所以你可能有竞争条件。不管这种情况只发生一次还是多次。

      到该点之前未定义的值是否要更改?如果是这样,请使用惰性 val。它有一个同步问题,可能会减慢高性能代码,但可以满足您的用例。

      【讨论】:

      • 我看到了竞争条件。谢谢你告诉我lazy val,我直到现在才用它,我确实想延迟新添加字段的初始化,我想它不会破坏任何提到的......
      猜你喜欢
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-26
      • 2011-04-18
      • 1970-01-01
      • 2021-01-18
      • 2012-09-08
      相关资源
      最近更新 更多