摆脱Scala

时间:2016-05-26 04:55:44

标签: scala

我已经使用以下签名

定义了一个过滤方法
def filterAcc(predicate: Element => Boolean, acc: ElementSet): ElementSet = {
  // filter elements which satisfy the predicate into new Set
  var newAccumulator = if (predicate(this.value) acc.add(this.value) else acc
  newAccumulator = this.leftChild(predicate, newAccumulator)
  this.rightChild(predicate, newAccumulator)
}

IDE正在抱怨以下

Avoid Mutable local variables

我的用例如下

  1. add方法在添加元素后返回一个新的Set所以我必须将它接收到另一个变量中。
  2. 同样,leftChild.filterAcc会将新的累积器作为新元素集返回
  3. 因此,每当我呼叫addfilterAcc时,我都必须收到一个新变量。编写这段代码的正确方法是什么。

    您可以假设逻辑是正确的。我只是想深入研究面向Scala的代码流,所以想知道编写这种类型逻辑的最佳实践,而不会出现警告/错误。

3 个答案:

答案 0 :(得分:4)

没有明显需要使newAccumulator可变。只需定义一个新的不可变val

  val newAccumulator = if (predicate(this.value) acc.add(this.value) else acc
  val newerAccumulator = this.leftChild(predicate, newAccumulator)
  this.rightChild(predicate, newerAccumulator)

实际上代码可以进一步压缩:但我选择不这样做以允许你拥有当前的可读性水平。

答案 1 :(得分:0)

您可以使用以下方法来避免var

def filterAcc(predicate: Element => Boolean, acc: ElementSet): ElementSet = {
    this.rightChild(predicate, this.leftChild(predicate, applyPredicate(predicate, acc)))
  }

def applyPredicate(predicate: Element => Boolean, acc: ElementSet) = if (predicate(this.value) acc.add(this.value) else acc

答案 2 :(得分:0)

在这种情况下,我根本不会使用命名val来调用leftChild。 @ javadba的答案更接近原作,但更具可读性是一个观点问题:

def filterAcc(predicate: Element => Boolean, acc: ElementSet): ElementSet = {
  // filter elements which satisfy the predicate into new Set
  val newAccumulator = if (predicate(this.value) acc.add(this.value) else acc
  this.rightChild(predicate, this.leftChild(predicate, newAccumulator))
}