PHP - причины использовать итераторы?

Я просматривал руководство сегодня и заметил различные итераторы. Мне кажется, что все они несколько бессмысленны; Я не вижу причин использовать их, если вы не предпочитаете их синтаксис или не знаете, как написать рекурсивную функцию. Есть ли причины использовать встроенные итераторы в PHP вместо простого написания цикла или создания рекурсивного метода?

Я только ищу фактические ответы, а не субъективные предпочтения (то есть: мне все равно, если вы думаете, что это более "читабельно" или "более объектно-ориентированный", я хочу знать, если они быстрее, предлагают функциональность, которая может не может быть достигнуто при прокате собственного и т. д.).

5 ответов

Решение

Я считаю, что основной причиной является универсальность. Они не делают вещи более читабельными, и вы можете выполнить большую часть того, что делают итераторы spl, с помощью простого foreach,

Но итераторы могут служить своего рода сжатым циклом или источником цикла, который вы можете передавать. Вы можете иметь более разнообразные источники данных, чем просто список / массив. И реальным преимуществом является то, что вы можете обернуть или сложить их для агрегации.

Наименование несколько неочевидно, но я думаю, вы могли бы использовать AppendIterator например, чтобы объединить статический список имен файлов и результат DirectoryIterator, Или иначе обернуть это в LimitIterator вместо того, чтобы зашить это в for состояние. Все это довольно простые функции и могут быть сделаны вручную в foreach. Но хотя бы RegexIterator а также FilterIterator кажется подходящим, чтобы уменьшить сложность.

Но в конце концов это действительно стилистический выбор. Это имеет смысл, если у вас есть пользовательские объекты, которые что-то пересекают (например, объект VFS, который может указывать на реальные файлы или записи в базе данных). Но даже тогда вы могли бы просто iterator_to_array преобразовать такой список и использовать обычный foreach -Более-массив.

Единственный случай, когда действительно необходимо отдавать предпочтение итераторам, это если источник данных неограниченного размера. Развернутые массивы для использования в foreach может потреблять больше памяти, чем итератор, который может извлекать элемент за элементом.

Основным преимуществом итераторов является то, что они абстрагируют понятие итерации. Это означает, что любые поставщики данных могут использоваться через один и тот же интерфейс. И именно здесь вы можете воспользоваться ими:

  • Лень
  • Уменьшенное использование памяти
  • Состав

Лень

С поставщиками данных данные выбираются только тогда, когда они вам действительно нужны (например, когда вы выполняете итерацию).

Уменьшенное использование памяти

Итераторы рекомендуют вам обрабатывать данные итеративно, а не буферизировать их в памяти. Хотя это можно сделать без итераторов, предоставляемые ими абстракции скрывают реализацию, что делает их действительно простыми в использовании.

Состав

Что сказал Марио


Юозас Казюкенас недавно написал в блоге сообщение о том, как он может использовать итераторы для имитации ленивых вычислений в PHP. Подробно о некоторых вещах, которые я упомянул.

На этот вопрос может быть очень много разных ответов, но правильные ответы, вероятно, можно обобщить так: Итератор может использоваться для итерации чего-либо более сложного, чем простой массив.

Одним из примеров является своего рода ORM или построитель запросов. Предположим, у нас есть один - использование может выглядеть так:

$friends = new Model_Friend();
$friends = $people->where('age','>',30)->where('gender','=','female');
foreach ($friends as $friend) {
    echo $friend->name;
}

Один простой пример: реализация объекта, доступ к которому можно получить как массив. SimpleXML является хорошим примером мощного поведения, которое может быть достигнуто с помощью этого.

Для этого вы могли бы implement Iterator интерфейс, который определяет методы public current(), public key(), public next(), public rewind() а также public valid(),

Или вы можете просто implement альтернатива IteratorAggregate интерфейс, который определяет один метод public getIterator() который просто возвращает итератор для внутренних данных, которые вы хотите предоставить.

Обязательно ознакомьтесь с примерами вышеупомянутых интерфейсов, и вы увидите преимущество.

Итераторы такие же быстрые, как и все остальное, но с более легким интерфейсом и, возможно, большим количеством пустяков, которые можно обернуть. Однако главное преимущество заключается не в том, что вам может понадобиться прямо сейчас, а в том, как вы можете расширить их для решения ваших будущих проблем (и они придут!), и это то, что мы, старые парни, называем "спасение твоей будущей задницы".:)

Другие вопросы по тегам