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