Cómo hacer que un tipo personalizado sea iterable en Rust.

Descubre cómo implementar la iteración en un tipo personalizado en Rust y optimiza tus procesos de desarrollo. Aprende cómo sacar el máximo provecho de tu código con este tutorial paso a paso.

11 nov 2025 • 6 min de lectura • Equipo Q2BSTUDIO

Cómo implementar la iteración en un tipo personalizado en Rust.

En este artículo explico cómo hacer que un tipo personalizado en Rust sea iterable implementando las traits IntoIterator, Iterator, FromIterator y Extend, y cómo añadir los métodos iter, iter_mut e into_iter a un contenedor como ArrayVec. También destaco por qué estas implementaciones son importantes en escenarios sin heap y en sistemas embebidos, y cómo estas técnicas encajan con servicios profesionales de desarrollo como los que ofrece Q2BSTUDIO.

Resumen rápido del reto y la idea general: ArrayVec es un envoltorio sobre un array de tamaño fijo que usa MaybeUninit para almacenar elementos sin inicializar en la pila o en memoria estática. Para que ArrayVec sea usable en bucles for y en la API de iteradores de la stdlib debemos hacer varias cosas: 1 crear un iterador que consuma ArrayVec y que devuelva elementos por valor, 2 permitir iteración por referencia y por referencia mutable usando los iteradores de slice, 3 implementar FromIterator para poder usar collect y 4 implementar Extend para poder añadir elementos desde cualquier iterator.

Iteradores por referencia: iter y iter_mut. Las versiones por referencia son las más sencillas. ArrayVec expone métodos as_slice y as_mut_slice que convierten los primeros len elementos inicializados en slices. A partir de esos slices se obtienen iteradores estándar slice::Iter y slice::IterMut, por ejemplo con métodos iter que devuelven as_slice().iter() y iter_mut que devuelven as_mut_slice().iter_mut(). Con esto ya se habilita que for x in &arr_vec o for x in &mut arr_vec funcionen y que se puedan encadenar adaptadores como map o filter.

Iterador consumiendo el contenedor: ArrayVecIntoIter. Para IntoIterator por valor hay que construir un tipo iterador concreto, por ejemplo ArrayVecIntoIter con campos values que es el array de MaybeUninit, len que indica cuántos elementos estaban inicializados, e index que lleva la posición de iteración. ArrayVecIntoIter implementa Iterator con Item = T y el método next hace: si index >= len devuelve None; en caso contrario lee el elemento seguro usando assume_init_read desde MaybeUninit, incrementa index y devuelve el valor. También es aconsejable implementar size_hint devolviendo el número restante.

Por qué implementar Drop en ArrayVecIntoIter. Cuando el iterador es creado a partir del ArrayVec original, los campos se mueven dentro del iterador. Si el iterador se deja caer sin haber consumido todos los elementos hay que asegurarse de llamar a assume_init_drop sobre los elementos no leídos entre index y len para evitar fugas de memoria o dobles liberaciones. Por eso ArrayVecIntoIter debe implementar Drop y en su drop iterar i desde index hasta len y llamar a assume_init_drop por cada slot.

Cómo pasar los datos desde ArrayVec a ArrayVecIntoIter sin provocar un doble drop. ArrayVec implementa Drop y su destructor accede a sus campos para liberar los elementos inicializados. Por ello no se puede mover directamente self.values fuera de self sin impedir que Drop se ejecute sobre un objeto partially moved. La solución es envolver self en core::mem::ManuallyDrop, luego usar ptr::read para leer bitwise los campos values y len hacia el nuevo ArrayVecIntoIter. De esta manera se evita que el destructor de ArrayVec se ejecute sobre datos ya movidos y el Drop del iterador queda responsable de liberar lo que quede.

IntoIterator para referencias y referencias mutables. Además del caso consumiendo el contenedor, se implementa IntoIterator para &ArrayVec y &mut ArrayVec devolviendo los iteradores de slice. Estas impls son simples: IntoIterator for &ArrayVec produce Iter con Item = &T y usa as_slice().iter(); IntoIterator for &mut ArrayVec produce IterMut con Item = &mut T y usa as_mut_slice().iter_mut().

FromIterator para colecciones. Implementar FromIterator permite usar collect para convertir cualquier iterator en un ArrayVec. La implementación típica crea un nuevo ArrayVec vacío, obtiene el iterator y utiliza size_hint para optimizar: si la cota inferior supera la capacidad N se puede tomar solo N elementos con take y evitar trabajo innecesario; en el caso general se itera empujando items con try_push hasta que el buffer se llene. Los items extra se descartan o se truncan según la política del contenedor.

Extend para añadir elementos desde un iterator. Extend es similar a FromIterator pero opera sobre &mut self. Recorre el iterator y llama a try_push por cada elemento hasta que try_push falle porque el ArrayVec está lleno, en cuyo caso se puede romper el bucle. Esto habilita patrones como arr_vec.extend(other_iterable) para rellenar colecciones sin realloc.

Funcionalidad auxiliar show_init. Para depuración o tests puede ser útil un método show_init que devuelva una vista de los N slots como Some(valor) para las posiciones inicializadas y None para los no inicializados. Esta función sólo es segura si T: Copy, porque internamente copia valores primitivos con un acceso seguro para evitar mover elementos no copiables y provocar uso después de liberar. Para tipos no copy la inspección directa de slots internos no es segura sin mayor control de ownership.

Pruebas y comportamiento en tiempo de ejecución. Con las impls descritas, ArrayVec puede iterarse por referencia y por valor; el iterador por valor traslada la propiedad correctamente y su Drop se encarga de los elementos no consumidos. En sistemas embebidos esto permite estructuras tipo Vec sin heap, mejorando rendimiento y control de recursos.

Por qué esto importa en proyectos reales. Si su proyecto requiere soluciones de alto rendimiento y control de memoria, como en sistemas embebidos, IoT o componentes críticos, usar contenedores sin heap y entender cómo implementar iteradores garantiza APIs seguras, predecibles y eficientes. En Q2BSTUDIO combinamos ese conocimiento en Rust con prácticas de ingeniería para entregar aplicaciones a medida. Si necesita desarrollar una aplicación segura y eficiente podemos ayudar desde el diseño hasta la puesta en producción con experiencia en software a medida y desarrollo multiplataforma y le invitamos a conocer nuestra oferta de desarrollo de aplicaciones y software a medida.

Servicios complementarios y posicionamiento. Además de desarrollo en Rust y arquitecturas embebidas, Q2BSTUDIO ofrece soluciones de inteligencia artificial, agentes IA y machine learning para empresas, servicios de ciberseguridad y pentesting, y despliegue en la nube con servicios cloud aws y azure. Si su proyecto requiere integración con analítica y cuadros de mando, trabajamos con servicios de inteligencia de negocio y Power BI para convertir datos en decisiones. Consulte nuestras capacidades en servicios de inteligencia artificial.

Palabras clave relacionadas: aplicaciones a medida, software a medida, inteligencia artificial, ciberseguridad, servicios cloud aws y azure, servicios inteligencia de negocio, ia para empresas, agentes IA, power bi. Estas capacidades combinadas permiten ofrecer soluciones end to end desde la idea hasta la operación segura y escalable.

Conclusión rápida: para hacer iterable un tipo personalizado en Rust hay que implementar IntoIterator en sus variantes por valor, por referencia y por referencia mutable; crear un iterador consumible que implemente Iterator y Drop cuando se manejen buffers con MaybeUninit; y complementar la API con FromIterator y Extend para interoperar con la extensa familia de adaptadores de iteradores. Estas técnicas permiten construir colecciones seguras y eficientes ideales para aplicaciones a medida y entornos con restricciones de recursos.

Si quiere que le ayudemos a diseñar e implementar soluciones a medida en Rust o integrar estas ideas en un producto con requisitos de seguridad y escalabilidad contacte con Q2BSTUDIO para explorar opciones de desarrollo, ciberseguridad, servicios cloud y proyectos de inteligencia de negocio.

¿UNA PAUSA?

Juega un momento antes de irte

NUESTROS SERVICIOS

Cómo podemos ayudarte

¿Tienes un proyecto en mente?

Cuéntanos tu visión y la convertimos en una solución de software. Sea cual sea el alcance, hacemos realidad tu idea.