문제

$arrayIter = new ArrayIterator( array(1, 2) );
$iterIter = new IteratorIterator($arrayIter);

var_dump($iterIter->valid()); //false
var_dump($arrayIter->valid()); //true

내가 처음 전화하면 $ iteriter-> Rewind (), 그 다음에 $ iteriter-> valid () 사실이다. Rewind ()를 호출 해야하는 이유가 궁금합니다. 나는 그것에 대한 좋은 이유가 있다고 생각하지만, 내부 반복자가있는 상태에서 단순히 반복을 시작하고 반복을 시작하기 전에 되감기위한 옵션으로 남겨두기를 기대했을 것입니다.

다음 ()에게 전화는 또한 "유효한"상태에 넣는 것 같습니다 (다음 위치로 발전하지만 이전에 첫 번째 위치에 있음을 시사합니다).

$arrayIter = new ArrayIterator(array(1,2));
$iterIter = new IteratorIterator($arrayIter);

$iterIter->next();
var_dump($iterIter->valid()); 

다시 말하지만, 내부 반복기가 유효한 상태에 있음에도 불구하고 Rewind ()에게 전화 해야하는 이유가 궁금합니다.

도움이 되었습니까?

해결책

신선한 반복기를 사용하면 포지션이 초기화되지 않으며, 성능의 이유로 다른 반복자 위에 반복기를 쌓을 수 있습니다. 건설 중에 모든 성능 영향이있을 경우 일부 반복자가 추가로 첫 번째 값을 변경할 수 있습니다. 생성자가 실행되었습니다. 이는 반복자에게 알려지지 않았습니다.

반복자는 일반적으로 rewind ()를 먼저 수행하는 foreach ()에 의해 실행됩니다.

다른 팁

연장하는 동안 IteratorIterator 클래스 전체 반복자 인터페이스 구현 및/또는 반복자의 데코레이터를 만들기위한 클래스.

그 데코레이터는 이미 문제에 대한 해결책이므로 불일치를 제거하기 위해 누락 된 기능 만 구현하면됩니다. 자동 복장이 필요하지 않습니다.

class IteratorDecorator extends IteratorIterator
{
    public function valid()
    {
        return $this->getInnerIterator()->valid();
    }
}

예 : 당신이있는 경우 Iterator 기본적으로 유효한 객체 (예 : ArrayIterator:

$it = new ArrayIterator(array(1));
var_dump($it->valid());             # bool(true)

$itit = new IteratorIterator($it);
var_dump($itit->valid());           # bool(false)

이것은의 불일치를 보여줍니다 IteratorIterator 잘 구현, IteratorIterator 객체는 내부를 올바르게 반영하지 않습니다 ArrayIterator상태. 사용 IteratorDecorator 이것을 치료할 수 있습니다 :

$decor = new IteratorDecorator($it);
var_dump($decor->valid());          # bool(true)

그리고 여기까지 후주했다면 여기에 또 다른 특별한 사례가 있습니다. rewind 내부 반복자를 사용하면 만 사용할 수 있습니다. NoRewindIterator 유효성을 올바르게 반환합니다.

$noretit = new NoRewindIterator($it);
var_dump($noretit->valid());        # bool(true)

Johannes "No Auto-Lewind"논쟁을 고려하면 이것은 의미가 있습니다. NoRewindIterator 반복자를 되 돌리지 말아야하고 내부 반복자의 유효성을 올바르게 보여줄 것으로 예상합니다.

그러나 IteratorDecorator 쇼, 나는 불일치를 제거하기 위해 어떤 종류의 자동 복장도하지 않습니다.

@johannes가 말했듯이, 위치는 IteratorIterator 따라서 다른 방법 중 하나가 실행되거나 oreach ()와 함께 사용되기 전에 유효하지 않습니다.

시도하십시오

var_dump( $iterIter->current() ); // NULL
var_dump( $iterIter->getInnerIterator()->current() ); // 1

그리고 또한

$iterIter->rewind();
var_dump( $iterIter->current() ); // 1
var_dump( $iterIter->getInnerIterator()->->current() );  // 1

또한 Unitiliazed iteratoriterator에서 다음과 같습니다.

$iterIter->next(); // 2
var_dump( $iterIter->current()) ; // 2 (from NULL to 2)
var_dump( $iterIter->getInnerIterator()->current() );  // 2

주목하십시오 $arrayIter 코드 스 니펫에서 동일합니다 $iterIter->getInnerIterator().

그것이 약간의 빛을 흘리기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top