简体   繁体   English

什么 PHP 代码访问 Iterator 接口相当于一个 foreach 循环?

[英]What PHP code accessing Iterator interface is equivalent to a foreach loop?

Assume we have an Iteraror .假设我们有一个Iteraror What code is equivalent to foreach ing it?什么代码相当于foreach呢?

function foreach_(Iterator $i): void
{
    foreach ($i as $k => $v) {
    }
}

The following code is equivalent:下面的代码是等价的:

function for_(Iterator $i): void
{
    for ($i->rewind(); $i->valid(); $i->next()) {
        $i->current();
        $i->key();
    }
}

Here is how I tested:这是我的测试方法:

class IteratorTest extends TestCase
{
    /**
     * @dataProvider provide
     */
    public function testDoesTheSameWithIterator(
        Iterator $i, 
        callable $expectedFn, 
        callable $actualFn
    ): void {
        $expectedI = new Iterator_($i);
        $actualI = new Iterator_($i);

        $expectedFn($expectedI);
        $actualFn($actualI);

        var_export($expectedI->calls);
        self::assertSame($expectedI->calls, $actualI->calls);
    }

    public function provide(): array
    {
        return [
            'for iterator vs foreach' => [
                new ArrayIterator(['a' => 1, 2 => 'b', 3 => null]),
                __NAMESPACE__ . '\foreach_',
                __NAMESPACE__ . '\for_',
            ],
        ];
    }
}

class Iterator_ implements Iterator
{
    public array $calls = [];
    private Iterator $i;

    public function __construct(Iterator $i)
    {
        $this->i = $i;
    }

    public function __call($method, $arguments)
    {
        $return = $this->i->$method(...$arguments);
        $this->calls[] = compact('method', 'arguments', 'return');
        return $return;
    }

    public function current()
    {
        return $this->__call(__FUNCTION__, func_get_args());
    }

    public function next(): void
    {
        $this->__call(__FUNCTION__, func_get_args());
    }

    public function key()
    {
        return $this->__call(__FUNCTION__, func_get_args());
    }

    public function valid(): bool
    {
        return $this->__call(__FUNCTION__, func_get_args());
    }

    public function rewind(): void
    {
        $this->__call(__FUNCTION__, func_get_args());
    }
}

Here's what the test outputs:这是测试输出的内容:

array (
  0 => 
  array (
    'method' => 'rewind',
    'arguments' => 
    array (
    ),
    'return' => NULL,
  ),
  1 => 
  array (
    'method' => 'valid',
    'arguments' => 
    array (
    ),
    'return' => true,
  ),
  2 => 
  array (
    'method' => 'current',
    'arguments' => 
    array (
    ),
    'return' => 1,
  ),
  3 => 
  array (
    'method' => 'key',
    'arguments' => 
    array (
    ),
    'return' => 'a',
  ),
  4 => 
  array (
    'method' => 'next',
    'arguments' => 
    array (
    ),
    'return' => NULL,
  ),
  5 => 
  array (
    'method' => 'valid',
    'arguments' => 
    array (
    ),
    'return' => true,
  ),
  6 => 
  array (
    'method' => 'current',
    'arguments' => 
    array (
    ),
    'return' => 'b',
  ),
  7 => 
  array (
    'method' => 'key',
    'arguments' => 
    array (
    ),
    'return' => 2,
  ),
  8 => 
  array (
    'method' => 'next',
    'arguments' => 
    array (
    ),
    'return' => NULL,
  ),
  9 => 
  array (
    'method' => 'valid',
    'arguments' => 
    array (
    ),
    'return' => true,
  ),
  10 => 
  array (
    'method' => 'current',
    'arguments' => 
    array (
    ),
    'return' => NULL,
  ),
  11 => 
  array (
    'method' => 'key',
    'arguments' => 
    array (
    ),
    'return' => 3,
  ),
  12 => 
  array (
    'method' => 'next',
    'arguments' => 
    array (
    ),
    'return' => NULL,
  ),
  13 => 
  array (
    'method' => 'valid',
    'arguments' => 
    array (
    ),
    'return' => false,
  ),
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM