PHP - причины использования итераторов? - PullRequest
23 голосов
/ 06 июня 2011

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

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

Ответы [ 5 ]

18 голосов
/ 06 июня 2011

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

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

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

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

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

16 голосов
/ 06 июня 2011

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

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

Лень

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

Сокращение использования памяти

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

Состав

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


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

10 голосов
/ 06 июня 2011

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

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

$friends = new Model_Friend();
$friends = $people->where('age','>',30)->where('gender','=','female');
foreach ($friends as $friend) {
    echo $friend->name;
}
7 голосов
/ 06 июня 2011

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

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

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

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

1 голос
/ 06 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...