scala - Scala 中函数字面量的分配

标签 scala

我有一个代表销售订单的类:
class SalesOrder(val f01:String, val f02:Int, ..., f50:Date)fXX字段有多种类型。我面临着为我的订单创建审计跟踪的问题。给定该类的两个实例,我必须确定哪些字段已更改。我想出了以下几点:

class SalesOrder(val f01:String, val f02:Int, ..., val f50:Date){

  def auditDifferences(that:SalesOrder): List[String] = {

    def diff[A](fieldName:String, getField: SalesOrder => A) =
      if(getField(this) != getField(that)) Some(fieldName) else None

    val diffList = diff("f01", _.f01) :: diff("f02", _.f02) :: ...
                :: diff("f50", _.f50) :: Nil

    diffList.flatten
  }    
}

我想知道编译器如何处理所有 _.fXX函数:它们是只实例化一次(静态),并且可以被我的类的所有实例共享,还是每次我创建我的类的实例时都会被实例化?

我担心的是,由于我将使用大量 SalesOrder 实例,因此可能会产生大量垃圾。我应该使用不同的方法吗?

最佳答案

解决这个问题的一种干净的方法是使用标准库的 Ordering type class .例如:

class SalesOrder(val f01: String, val f02: Int, val f03: Char) {
  def diff(that: SalesOrder) = SalesOrder.fieldOrderings.collect {
    case (name, ord) if !ord.equiv(this, that) => name
  }
}

object SalesOrder {
  val fieldOrderings: List[(String, Ordering[SalesOrder])] = List(
    "f01" -> Ordering.by(_.f01),
    "f02" -> Ordering.by(_.f02),
    "f03" -> Ordering.by(_.f03)
  )
}

进而:
scala> val orderA = new SalesOrder("a", 1, 'a')
orderA: SalesOrder = SalesOrder@5827384f

scala> val orderB = new SalesOrder("b", 1, 'b')
orderB: SalesOrder = SalesOrder@3bf2e1c7

scala> orderA diff orderB
res0: List[String] = List(f01, f03)

您几乎肯定不需要担心原始配方的性能,但由于不相关的原因,这个版本(可以说)更好。

关于scala - Scala 中函数字面量的分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17394302/

相关文章:

scala - Play 框架 2.5 记录 `?` 问号而不是行号

java - 类型与类型定义的交集

scala - 如何在 Scala 案例类中转义减号

Scala 编写 lisp-like progn 的方法?

scala - 优雅的AST模型

scala - mllib Vector 的最大值?

scala - 二叉树折叠

scala - 在 HList 上做协变过滤器

scala - 使用 <> 在 Scala 中模拟 !=

scala - 如何在 Scala 中将类型作为参数传递?