1

今日、このPHP: Iteratorsページに出くわしましたが、なぜこれらのクラスが必要なのか疑問に思っています。それらが目的を果たしていると仮定したいと思います。そうでなければ、それらはPHPにはありません。これらを行うための非常に簡単な方法がすでにあるのに、私はそのようなアイテムの利点を見るのに苦労しています.

PHP は、より立派なオブジェクト指向プログラミング言語であるという誤りを犯していますか? それとも、これを行うことには本当に利点がありますか?

これを行うには 2 つの方法があることを示す良い例が、 ArrayIterator に関する PHP コメントで見つかりました。

<?php
$fruits = array(
    "apple" => "yummy",
    "orange" => "ah ya, nice",
    "grape" => "wow, I love it!",
    "plum" => "nah, not me"
);
$obj = new ArrayObject( $fruits );
$it = $obj->getIterator();

// How many items are we iterating over?
echo "Iterating over: " . $obj->count() . " values\n";

// Iterate over the values in the ArrayObject:
while( $it->valid() ) {
    echo $it->key() . "=" . $it->current() . "\n";
    $it->next();
}

// The good thing here is that it can be iterated with foreach loop

foreach ($it as $key=>$val)
echo $key.":".$val."\n";

/* Outputs something like */

Iterating over: 4 values
apple=yummy
orange=ah ya, nice
grape=wow, I love it!
plum=nah, not me

?>
4

4 に答える 4

5

イテレータが PHP に組み込まれているのは、配列などの組み込みオブジェクトのループに制限されるのではなく、任意のオブジェクトで一般的な言語構造 (foreach など) を使用できるためです。オブジェクトの内部状態を反復処理のために強制的に配列に変換するのは面倒です (そしてカプセル化を破ります)。大規模なデータセットの場合、システムのメモリが不足する可能性があります。iterable を使用すると、オブジェクト自体が要求された場合にのみ個々の要素を返すようにすることで、これらの問題を両方とも回避できます。

于 2012-06-20T12:57:05.507 に答える
1

私の例では、回答を Iterator に限定するのではなく、Traversable も含めます。

SimpleXML ( SimpleXMLElementおよびSimpleXMLIterator ) を見てください。

非常に便利で使いやすく、その機能を提供するクラスを拡張したという理由だけで、XML を反復処理/トラバースできるオブジェクトに変換できます。私は XML のかなりの部分を自分のやり方で foreach しましたが、それを提供するために車輪を再発明する必要がなかったことを非常に嬉しく思います。それらの使用例と存在する理由の例は他にもたくさんあると確信していますが、これらは配列ではないことからすぐに恩恵を受けた最初のポップアップでした。

于 2012-06-20T12:52:19.887 に答える
1

あなたの例は、 Iterator オブジェクトを使用する理由ではありません。ほとんどの場合、Iterator オブジェクトは、クラスを反復処理し、直接クラスを反復子として使用するために使用されます。

http://php.net/manual/de/class.iterator.php

ここに短い例があります。

単一の配列がある場合、配列に対して foreach を作成するのは非常に簡単です。

于 2012-06-20T12:44:11.573 に答える
0

IteratorAggregateをクラスに実装したいインスタンスに出くわすことがあります。そのため、プライベート メンバーを公開したり、公開関数を作成したりせずにイテレータを実行できます。

class BaseballTeams implements IteratorAggregate
{
    private $teams;

    public function __construct( )
    {
        $this->teams = explode( ',', "Tigers,Cubs,Orioles,Mariners,Yankees,Blue Jays,Marlins" );
    }

    public function getIterator( )
    {
        return new ArrayIterator( $this->teams );
    }
}

これで、次のようにプライベート $teams メンバーをループできます。

$baseball = new BaseballTeams( );

foreach ( $baseball as $n => $t )
{
    echo "<p>Team #$n: $t</p>";
}
于 2012-06-20T12:53:36.833 に答える