Php/docs/language.generators.comparison

提供:Dev Guides
< Php
移動先:案内検索

ジェネレータと Iterator オブジェクトとの比較

ジェネレータの最大のメリットは、シンプルに書けることです。 Iterator を実装するのに比べて、必要な決まり文句の数がかなり少なくなります。 また、ジェネレータを使ったコードのほうが、一般的に読みやすくなります。 たとえば、次の関数とクラスを比べてみましょう。これらはどちらも同じ働きをするものです。

<?phpfunction getLinesFromFile($fileName) {    if (!$fileHandle = fopen($fileName, 'r')) {        return;    }     while (false !== $line = fgets($fileHandle)) {        yield $line;    }     fclose($fileHandle);}// これを、下のクラスと比べてみると……class LineIterator implements Iterator {    protected $fileHandle;     protected $line;    protected $i;     public function __construct($fileName) {        if (!$this->fileHandle = fopen($fileName, 'r')) {            throw new RuntimeException('Couldn\'t open file "' . $fileName . '"');        }    }     public function rewind() {        fseek($this->fileHandle, 0);        $this->line = fgets($this->fileHandle);        $this->i = 0;    }     public function valid() {        return false !== $this->line;    }     public function current() {        return $this->line;    }     public function key() {        return $this->i;    }     public function next() {        if (false !== $this->line) {            $this->line = fgets($this->fileHandle);            $this->i++;        }    }     public function __destruct() {        fclose($this->fileHandle);    }}?>

しかし、柔軟性を実現するために犠牲にしていることもあります。 ジェネレータは前方にしか進めないイテレータなので、いったん反復処理が始まれば巻き戻すことができません。 これはつまり、同じジェネレータを何度も使い回せないということです。 ジェネレータ関数を呼んでもう一度作り直す必要があります。