如果一個Iterator已被部分或完全遍歷,再對其調用iterator_count()會返回剩餘元素數量或0。
錯誤示例:
<span><span><span class="hljs-variable">$it</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">ArrayIterator</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-number">4</span></span><span>]);
</span><span><span class="hljs-variable">$it</span></span><span>-></span><span><span class="hljs-title function_ invoke__">next</span></span><span>(); </span><span><span class="hljs-comment">// 移動了一步</span></span><span>
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-title function_ invoke__">iterator_count</span></span><span>(</span><span><span class="hljs-variable">$it</span></span><span>); </span><span><span class="hljs-comment">// 返回 3 而不是 4</span></span><span>
</span></span>
解決方案:
在調用iterator_count()之前,先重置迭代器:
<span><span><span class="hljs-variable">$it</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">ArrayIterator</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>, </span><span><span class="hljs-number">4</span></span><span>]);
</span><span><span class="hljs-variable">$it</span></span><span>-></span><span><span class="hljs-title function_ invoke__">rewind</span></span><span>(); </span><span><span class="hljs-comment">// 重置指針</span></span><span>
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-title function_ invoke__">iterator_count</span></span><span>(</span><span><span class="hljs-variable">$it</span></span><span>); </span><span><span class="hljs-comment">// 返回 4</span></span><span>
</span></span>
iterator_count()會完全遍歷迭代器。如果數據集龐大或迭代器中包含複雜邏輯,可能引發嚴重的性能問題。
示例:
<span><span><span class="hljs-variable">$it</span></span><span> = </span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">InfiniteIterator</span></span><span>(</span><span><span class="hljs-keyword">new</span></span><span> </span><span><span class="hljs-built_in">ArrayIterator</span></span><span>([</span><span><span class="hljs-number">1</span></span><span>, </span><span><span class="hljs-number">2</span></span><span>, </span><span><span class="hljs-number">3</span></span><span>]));
</span><span><span class="hljs-variable">$count</span></span><span> = </span><span><span class="hljs-title function_ invoke__">iterator_count</span></span><span>(</span><span><span class="hljs-variable">$it</span></span><span>); </span><span><span class="hljs-comment">// 永遠不會結束</span></span><span>
</span></span>
解決方案:
僅對有限、已知範圍的數據使用。
避免在無限或大型數據結構中直接調用。
考慮實現自定義計數邏輯。
使用前確保迭代器未被部分遍歷,或通過rewind()重置指針。
對不可重用的迭代器(如生成器)避免直接調用iterator_count() ,可使用iterator_to_array()轉換後再統計。
避免在無限或高消耗的迭代器上調用該函數,要先評估執行的代價。
寫測試代碼驗證行為,尤其是對第三方庫返回的Traversable類型對象。