PHP - Причины использования итераторов?
Я изучал руководство сегодня и заметил различные итераторы. Мне кажется, что все они несколько бессмысленны; Я не вижу причины использовать их, если вы предпочитаете их синтаксис, или не знаете, как написать рекурсивную функцию. Существуют ли какие-либо причины использовать встроенные итераторы в PHP для простого написания цикла или создания рекурсивного метода?
Я ищу только фактические ответы, а не субъективные предпочтения (т.е. меня не волнует, если вы считаете, что это более "читаемый" или "более объектно-ориентированный", я хочу знать, если они быстрее, предложите функциональность, которая не может быть достигнута при ее запуске и т.д.).
Ответы
Ответ 1
Я считаю, что главная причина - универсальность. Они не делают вещи более читаемыми, и вы можете выполнить большую часть того, что итераторы делают с помощью простого foreach
.
Но итераторы могут служить своего рода уплотненным контуром или источником цикла, который вы можете обойти. У вас могут быть более разнообразные источники данных, чем просто список/массив. И реальным преимуществом является то, что вы можете обертывать или складывать их для агрегации.
Именование несколько неочевидно, но я думаю, вы могли бы использовать AppendIterator
, чтобы, например, объединить статический список имен файлов и результат DirectoryIterator
. Или иначе оберните это в LimitIterator
вместо hardwiring, что в условие for
. Все это довольно простые функции, и их можно выполнять вручную в режиме foreach. Но по крайней мере RegexIterator
и FilterIterator
кажутся подходящими чтобы уменьшить некоторую сложность.
Но в конце концов это действительно стилистический выбор. Это имеет смысл, если у вас есть пользовательские объекты, которые пересекают что-либо (например, объект VFS, который может указывать на реальные файлы или записи в базе данных). Но даже тогда вы могли бы просто iterator_to_array
преобразовать такой список и использовать обычный foreach
-over-array.
Единственный случай - действительно, важно, чтобы итераторы предпочитали, если источник данных не ограничен по размеру. Развернутые массивы для использования в foreach
могут потреблять больше памяти, чем итератор, который может извлекать элемент за элементом.
Ответ 2
Основное преимущество итераторов заключается в том, что они абстрагируют концепцию итерации. Это означает, что любые поставщики данных могут использоваться через один и тот же интерфейс. И именно там, где вы можете их использовать:
- Лень
- Сокращение использования памяти
- Состав
Лень
С поставщиками данных данные извлекаются только тогда, когда вам это действительно нужно (например, когда вы итерации).
Сокращение использования памяти
Итераторы рекомендуют обрабатывать данные итеративно, а не буферизировать их в памяти. Хотя это можно сделать без итераторов, абстракции, которые они предоставляют, скрывают реализацию, которая делает их очень простыми в использовании.
Состав
Что сказал Марио.
Недавно Juozas Kaziukėnas написал сообщение о том, как он мог использовать итераторы для эмуляции ленивой оценки в PHP. Он подробно рассказывает о некоторых вещах, о которых я упоминал.
Ответ 3
Один простой пример: реализация объекта, к которому можно получить доступ и пройденного как массив. SimpleXML - хороший пример мощного поведения, которое может быть достигнуто с этим.
Для этого вы можете implement
Iterator
интерфейс, который определяет методы public current()
, public key()
, public next()
, public rewind()
и public valid()
.
Или вы можете просто implement
альтернативный IteratorAggregate
интерфейс, который определяет один метод public getIterator()
, который просто возвращает Итератор для внутренних данных, которые вы хотите открыть.
Обязательно ознакомьтесь с примерами вышеуказанных интерфейсов, и вы увидите преимущество.
Ответ 4
Вопрос может иметь очень широкий спектр ответов, но правильные ответы, вероятно, можно суммировать как: Итератор может использоваться для итерации чего-либо более сложного, чем простой массив.
Один пример - это какой-то ORM или построитель запросов. Предположим, что у нас есть одно - использование этого может выглядеть так:
$friends = new Model_Friend();
$friends = $people->where('age','>',30)->where('gender','=','female');
foreach ($friends as $friend) {
echo $friend->name;
}
Ответ 5
Итераторы так же быстро, как и все остальное, но с более легким интерфейсом и, возможно, большим количеством слов, чтобы обернуть его. Однако главное преимущество - не то, что вам может понадобиться прямо сейчас, но как вы можете расширить их, чтобы справиться с будущие проблемы (и они придут!), и это то, что мы, старые мальчики, называем "спасая вашу будущую задницу".:)