1

Twitterで公開されているドキュメント「EffectiveScala 」には、次のコード例があります。

class Pool(conns: Seq[Conn]) {
  private[this] val waiters = new Broker[Conn]
  private[this] val returnConn = new Broker[Conn]

  val get: Offer[Conn] = waiters.recv
  def put(c: Conn) { returnConn ! c }

  private[this] def loop(connq: Queue[Conn]) {
    Offer.choose(
      if (connq.isEmpty) Offer.never else {
        val (head, rest) = connq.dequeue
        waiters.send(head) { _ => loop(rest) }
      },
      returnConn.recv { c => loop(connq enqueue c) }
    ).sync()
  }

  loop(Queue.empty ++ conns)
}

コードは末尾再帰のようには見えず、そのように注釈が付けられていません。これはおそらくプログラムの存続期間中実行されたままになる接続プールであるため、このようなプールが最終的にスタックを爆破し、StackOverflowExceptionを生成するのを防ぐにはどうすればよいでしょうか。

4

1 に答える 1

6

コードは再帰的ではありません。loop自分自身を呼び出しません。再び呼び出すクロージャ{ _ => loop(rest) }{ c => loop(connq enqueue c) }towaiters.sendおよびreturnConn.recvそれぞれを渡しloopます。再帰がないため、スタック オーバーフローはありません。

于 2012-09-14T08:02:13.267 に答える