PHP の IteratorIterator の理解 (コード例)

不言
リリース: 2023-04-04 10:56:01
転載
2539 人が閲覧しました

この記事の内容はphpのIteratorIteratorの理解(コード例)であり、一定の参考価値があるので、困っている友人は参考にしていただければ幸いです。

phpのIteratorIterator個人的な理解

最近またlaravelのソースコードをいじり始めたのですが、1年以上使っていなかったのでほとんど忘れていました。見るたびにそこから始めます、中学校でたくさん習いました、分からないことがあればマニュアルで調べてください。設定ファイル (config/*.php) を読み込む部分を見ました。コード内では spl クラス ライブラリとインターフェイスが多用されています。今日は IteratorIterator クラスについて話します。インターネット上の情報が少なすぎるので、私はあまり頭が良くありません。何度かやりました。Genius にはいくつかの手がかりがあり、以下はそれについての私の個人的な理解です。

IteratorIterator の概要

IteratorIterator はイテレータ ラッパーであり、もちろんイテレータ自体でもあります。それ (Outer と呼ばれると仮定します) は、インスタンス化するときに、Traversable インターフェイス タイプ (Inner と呼ばれると仮定します) を実装するイテレータ インスタンスを渡す必要があります。もちろん、この受信イテレータ パラメータ Inner は、Outer の getInnerIterator メソッドを通じて取得できます。内部反復子 Inner は、Outer の rewind()、next()、valid()、current()、および key() メソッドを通じて処理できます。

理解すべき重要なポイント

  1. Outer、Outer をトラバースするプロセスでは、rewind()、next()、valid()、current()、および key() だけを実行します。あらゆる呼び出し は、内部反復子 Inner に転送されます。

  2. Outer は、転送によって返された結果をラップできますが、これは Inner には影響しません。

コードのデモ

<?php
namespace young;class InnerIterator implements \Iterator{
    private $dates;
    private $position;

    public function __construct($dates = [])
    {
        $this->dates    = $dates;
        $this->position = 0;
    }

    public function rewind()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        reset($this->dates);
    }

    public function valid() 
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        if ($this->position >= count($this->dates)) {
            # code...
            return false;
        }
        return true;
    }

    public function current()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        return $this->dates[$this->position];
    }

    public function key()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        return $this->position;
    }

    public function next()
    {
        echo &#39;call &#39; . __METHOD__ . &#39;<br>&#39;;
        ++$this->position;
    }}class OuterIterator extends \IteratorIterator{
    function rewind()
    {
        echo __METHOD__ .  &#39;<br>&#39;;
        return parent::rewind();
    }
    
    function valid()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::valid();
    }
    
    function current()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::current() . &#39;_suffix&#39;;
    }
    
    function key()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::key() ;
    }
    
    function next()
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::next() ;
    }
    
    function getInnerIterator() 
    {
        echo __METHOD__ . &#39;<br>&#39;;
        return parent::getInnerIterator();
    }}$tmpArr = array(
    &#39;2018-10-01&#39;,
    &#39;2018-10-02&#39;,
    //&#39;2018-10-03&#39;,);$inner = new InnerIterator($tmpArr);$outer = new OuterIterator($inner);foreach ($outer as $key => $value) {
    # code...
    echo $key , &#39;=>&#39; , $value . &#39;<hr>&#39;;}
ログイン後にコピー

実行結果:

young\OuterIterator::rewind
ログイン後にコピー
call young\InnerIterator::rewind
call young\InnerIterator::valid
call young\InnerIterator::current
call young\InnerIterator::key
ログイン後にコピー
young\OuterIterator::valid
young\OuterIterator::current
young\OuterIterator::key
0=>2018-10-01_suffix
young\OuterIterator::next
ログイン後にコピー
call young\InnerIterator::next
call young\InnerIterator::valid
call young\InnerIterator::current
call young\InnerIterator::key
ログイン後にコピー
young\OuterIterator::valid
young\OuterIterator::current
young\OuterIterator::key
1=>2018-10-02_suffix
young\OuterIterator::next
ログイン後にコピー
call young\InnerIterator::next
call young\InnerIterator::valid
ログイン後にコピー
 young\OuterIterator::valid
 object(young\InnerIterator)#1 (2) { 
[“dates”:“young\InnerIterator”:private]=> array(2) { [0]=> 
string(10) “2018-10-01” [1]=> string(10) “2018-10-02” } 
[“position”:“young\InnerIterator”:private]=> int(2) }
ログイン後にコピー
結果分析

毎回アウター反復は最初に独自のメソッドを呼び出し、次にそれを Inner に転送します。

Outer の内部メソッドの戻り値は、メソッドに対する Inner の戻り値に基づいています。
Outer メソッドでは、Inner の戻り値に対して論理処理を行うことができます。
Inner の valid が false を返すと、外側のOuter も反復を停止します。
Outer のメソッドによる戻り値の変更は、Inner には影響しません。
Outer のメソッドは、反復プロセス中に getInnerIterator メソッドを実行しません。これは、Inner メソッドを取得するための呼び出しインターフェイスにすぎません。
#少し追加です

インターネットの情報を閲覧しているときにこのような疑問を見つけました

//假如这里还是使用了上面的两个类代码
<?php
namespace young;
class InnerIterator implements \Iterator
{
    //code 这里的代码假如和上面的一样
}
class OuterIterator extends \IteratorIterator
{
    //code 这里的代码假如和上面的一样
}
$outer->valid();           //false
$outer->current();         // _suffix  问题一
$outer->rewind();    
$outer->valid();            //true
$outer->current();         //2018-10-01_suffix
$outer->next()
$outer->rewind();
$outer->current();         //2018-10-02_suffix  问题二
ログイン後にコピー

ここで 2 つの質問があります。

    質問 1、なぜ current に値がなく、valid が false であるのか
  1. #質問 2、なぜ next と rewind の後に current が 2 番目の値であるのか
  2. # 上記の実行結果から、$outer は rewind を実行せず、$inner も実行しないことがわかります。そのため、valid は false を返し、current は null で、_suffix はそれ自体で結合されているだけです。
  3. 2 番目の問題も非常に奇妙です。私は今発見しました。$inner のポインタが前に進む限り、後戻りはできません。つまり、$inner の位置属性は、最初の次の後に 1 になります。巻き戻しても位置は1のままなので少しわかりにくいです。 。 。
$outer traversal 操作を実行すると、2 番目のパスでは値が出力されません。2 番目のパスで巻き戻し操作を実行したとしても、この操作は 2 番目のパスでは役に立ちません~~~

以上がPHP の IteratorIterator の理解 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート