2011-06-06 12 views
21

Estaba leyendo el manual hoy y noté el various iterators. Para mí, parece que todos son algo sin sentido; No veo una razón para usarlos a menos que prefiera su sintaxis, o no sepa cómo escribir una función recursiva. ¿Hay alguna razón para usar iteradores incorporados en PHP sobre simplemente escribir un bucle o hacer un método recursivo?PHP - Razones para usar Iterators?

Solo estoy buscando respuestas objetivas, no preferencias subjetivas (es decir: no me importa si piensas que es más "legible" u "más orientado a objetos", quiero saber si son más rápidos, ofrece una funcionalidad que no se puede lograr cuando lances la tuya, etc.).

+5

"más orientado a objetos" no es una opinión subjetiva; se adentra en el conjunto de características de su problema. Si se ocupa de objetos, no es subjetivo querer trabajar con ellos de una manera orientada a objetos. – AlexanderJohannesen

+0

Creo que "más orientado a objetos" es una opinión subjetiva en este caso porque la implementación lograda por los iteradores no está más orientada a objetos de lo que podría ser una implementación personalizada; no están más orientados a objetos que una solución alternativa orientada a objetos. – mrjminer

+1

Es un comentario extraño, dado que algunos iteradores operan en objetos específicos que los métodos tradicionales no funcionarán en absoluto (que es un punto muy importante). No puede tratar objetos como una matriz a menos que los convierta a una matriz, y con frecuencia eso simplemente no es posible; cualquier estructura que no sea de árbol te dará dolores de cabeza masivos. Si está iterando a través de un gráfico que depende de la semántica de algunas relaciones, esto es imposible sin iteradores, pero a menudo bastante trivial. Asi que. No, no es realmente subjetivo, a menos que seas Voltaire y profundices en el existencialismo. :) – AlexanderJohannesen

Respuesta

16

Creo que la razón principal es la versatilidad. No hacen las cosas más legibles y puedes lograr la mayoría de lo que hace el spl iterators con un simple foreach.

Pero los iteradores pueden servir como una fuente compactada de bucle o bucle que puede pasar. Puede tener fuentes de datos más diversas que solo una lista/matriz. Y la verdadera ventaja es que puedes envolverlos o apilarlos para la agregación.

La denominación es algo obvia, pero supongo que podría usar el AppendIterator para, por ejemplo, combinar una lista estática de nombres de archivos y el resultado de un DirectoryIterator. O bien, envuélvalo en un LimitIterator en lugar de cablearlo en una condición for. Todas estas son características bastante básicas y se pueden hacer de forma manual en un foreach. Pero al menos RegexIterator y FilterIterator parecen adecuados para reducir cierta complejidad.

Pero al final es realmente una elección estilística. Tendría más sentido si tiene objetos personalizados que atraviesan algo (por ejemplo, un objeto VFS que puede apuntar a archivos reales o entradas de la base de datos). Pero incluso entonces podría simplemente iterator_to_array convertir dicha lista, y usar una normal foreach -over-array.

El único caso fue que es realmente imperativo preferir los iteradores si la fuente de datos es de tamaño ilimitado. Las matrices desplegadas para su uso en un foreach pueden consumir más memoria que un iterador que puede recuperar elemento por elemento.

+0

Veo lo que quiere decir con fuentes de datos de tamaño ilimitado. Voy a tener que probar el uso de memoria/CPU con cada uno cuando tenga algo de tiempo. – mrjminer

+0

¿Puede una matriz ser una "fuente de datos de tamaño ilimitado"? Si no, ¿cuál es el punto para ArrayIterators? – Muc

+0

@Muc Una matriz no puede. Como aquellos tienen sus datos en la memoria. Pero los iteradores pueden, como la entrada puede resolverse dinámicamente desde los archivos/base de datos/entrada de socket/urand etc. – mario

7

Un ejemplo simple: Implementando un objeto que se puede acceder y recorrer como una matriz. SimpleXML es un buen ejemplo del poderoso comportamiento que se puede lograr con esto.

Para lograr esto se podía implement la Iterator interface que define los métodos public current(), public key(), public next(), public rewind() y public valid().

O simplemente puede implement la alternativa IteratorAggregate interface que define un método public getIterator() que simplemente devuelve un iterador para los datos internos que desea exponer.

Asegúrese de revisar los ejemplos de las interfaces anteriores y verá la ventaja.

+0

Gracias por el enlace a SimpleXML. No tengo tiempo para profundizar en este momento, pero una mirada rápida reveló que será un buen ejemplo. – mrjminer

+0

Esa es la cuestión: puede tener un objeto _also_ que sea transitable, junto con _otra_ funcionalidad. Por lo tanto, se presta a cualquier cosa que sea más complicada/avanzada que simplemente pasar por una estructura de datos simple. De lo contrario, es solo hinchazón, así que recuerda KISS y YAGNI. – DanMan

7

La pregunta puede tener una gran variedad de respuestas, pero las respuestas correctas probablemente se pueden resumir como: Iterator se puede utilizar para iterar cualquier cosa más compleja que la simple matriz.

Un ejemplo es algún tipo de ORM o generador de consultas.Asumamos que tenemos uno - a usarlo podría parecerse a lo siguiente:.

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

iteradores son tan rápido como cualquier otra cosa, pero con una interfaz más sencilla y tal vez más verbage a envolverlo en Sin embargo, la ventaja principal no lo es es posible que lo necesite en este momento, pero cómo puede ampliarlos para enfrentar sus problemas futuros (¡y ellos vendrán!), y eso es lo que los muchachos llamamos "salvar su trasero del futuro". :)

13

La principal ventaja de los iteradores es que abstraen el concepto de iteración. Esto significa que cualquier proveedor de datos se puede usar a través de la misma interfaz. Y eso es exactamente donde se puede tomar ventaja de ellos:

  • pereza
  • uso de memoria reducido
  • Composición

pereza

con proveedores de datos, los datos sólo es inverosímil cuando realmente lo necesita (p. ej., cuando itera).

uso de memoria reducido

iteradores que animan a procesar los datos de forma iterativa, en lugar de almacenar temporalmente en la memoria. Si bien es posible hacer esto sin iteradores, las abstracciones que proporcionan ocultan la implementación, lo que los hace realmente fáciles de usar.

Composición

Lo dijo Mario.


Juozas Kaziukėnas escribió recientemente un blog post de cómo podría utilizar iteradores para emular evaluación perezosa en PHP. Entra en detalles sobre algunas de las cosas que he mencionado.

Cuestiones relacionadas