2

Scala の標準ライブラリのいくつかのメソッドが可変状態で実装されているのはなぜですか?

たとえば、クラスfindの一部としてのメソッドは次のように実装されます。scala.Iterator

def find(p: A => Boolean): Option[A] = {
  var res: Option[A] = None
  while (res.isEmpty && hasNext) {
    val e = next()
    if (p(e)) res = Some(e)
  }
  res
}

@tailrecこれは、おそらく次のようなメソッドとして実装できた可能性があります

def findNew(p: A => Boolean): Option[A] = {

  @tailrec
  def findRec(e: A): Option[A] = {
    if (p(e)) Some(e)
    else {
      if (hasNext) findRec(next())
      else None
    }
  }

  if (hasNext) findRec(next())
  else None
}

ここで、1 つの引数が変更可能な状態の使用である可能性があり、ループがより効率的である可能性があると思います。これは、当然のことながら、ライブラリ コードでは非常に重要ですが、 'd メソッドwhileの場合は本当にそうなのでしょうか?@tailrec

4

3 に答える 3

4

彼が共有されていない限り、変更可能な状態を持っていても害はありません。

あなたの例では、変更可能な var に外部からアクセスする方法がないため、この変更可能な変数が副作用のために変更されることはありません。

可能な限り不変性を強制することは常に良いことですが、パフォーマンスが重要な場合、安全な方法で制約されている限り、ある程度の可変性を持っていても問題はありません。

注: イテレータは、副作用のないデータ構造であり、これにより奇妙な動作が発生する可能性がありますが、これは別の話であり、そのような方法でメソッドを設計する理由にはなりません。不変のデータ構造にもそのような方法があります。

于 2013-04-22T19:39:15.637 に答える
3

この場合、はおそらくループtailrecと同じパフォーマンスを発揮します。この場合、ループ ソリューションはより短く、より簡潔でwhileあると言えます。while

しかし、とにかくイテレータは変更可能な抽象化であるため、varその短いコード スニペットにローカルな、それを回避するための末尾再帰メソッドを持つことの利点は疑わしいものです。

于 2013-04-22T19:40:21.967 に答える