【问题标题】:Adding a field to Scala case class?向Scala案例类添加字段?
【发布时间】:2017-01-26 08:37:47
【问题描述】:

我在Pimp my Library pattern 上看到了一些博客,这些博客似乎可以很好地为类添加行为。

但是如果我有一个case class 并且我想add data members 呢?作为案例类,我无法对其进行扩展(不推荐/强烈反对从案例类继承)。这些皮条客模式中的任何一个都允许我向案例类添加数据吗?

【问题讨论】:

    标签: class scala case


    【解决方案1】:

    不 - 我不知道您如何才能完成这项工作,因为 enriched 实例 通常会被丢弃(注意:新的 pimp-my-library 模式称为enrich-my-library) .例如:

    scala> case class X(i: Int, s: String)
    defined class X
    
    scala> implicit class Y(x: X)  {
       |     var f: Float = 0F
       |   }
    defined class Y
    
    scala> X(1, "a")
    res17: X = X(1,a)
    
    scala> res17.f = 5F
    res17.f: Float = 0.0
    
    scala> res17.f
    res18: Float = 0.0
    

    你必须确保你持有被包装的实例:

    scala> res17: Y
    res19: Y = Y@4c2d27de
    
    scala> res19.f = 4
    res19.f: Float = 4.0
    
    scala> res19.f
    res20: Float = 4.0
    

    但是,我发现这在实践中没有用。你有一个包装器;你最好明确一点

    【讨论】:

      【解决方案2】:

      这不是办法。只是可能性的证明。通过这种方式,您可能会遇到很多问题。

      scala> :paste
      // Entering paste mode (ctrl-D to finish)
      
      case class A(i: Int)
      
      class B(a: A){
        var s: String = ""
      }
      
      object B{
        val as = scala.collection.mutable.WeakHashMap[A, B]()
      }
      
      implicit def a2b(a: A) = B.as.getOrElseUpdate(a, new B(a))
      
      // Exiting paste mode, now interpreting.
      
      defined class A
      defined class B
      defined module B
      a2b: (a: A)B
      
      scala> val a = A(1)
      a: A = A(1)
      
      scala> a.s = "test"
      
      scala> a.s
      res0: String = test
      

      WeakHashMap:一个哈希映射,其中包含对弱可达条目的引用。当不再(强)引用该键时,将从该映射中删除条目。这个类包装了 java.util.WeakHashMap。

      请注意,由于 case class 的覆盖 equals 方法,您会得到这种有趣的行为:

      scala> A(2).s = "test2"
      
      scala> A(2).s
      res2: String = test2
      

      因此您不应使用case class 或将其与override def equals(that: Any) = this eq that.asInstanceOf[AnyRef] 一起使用。

      【讨论】:

      • 请不要提出这样的建议。这不仅极其丑陋,而且不安全。
      • @drexin 如果你愿意,我可以使这个线程安全(在单个 jvm 上)。
      猜你喜欢
      • 2016-09-07
      • 1970-01-01
      • 2014-12-17
      • 2014-08-03
      • 2016-01-13
      • 1970-01-01
      • 2020-08-12
      • 2016-12-03
      • 2023-03-26
      相关资源
      最近更新 更多