2009-10-23 12 views
10

Estoy usando la estructura de listas doblemente enlazada de GLib, GList. Me gustaría saber si hay estándar macro para iterar sobre un GList. No pude encontrar nada de eso en la documentación de GLib. Como resultado, he creado mi propia macro, pero prefiero usar algo estándar si existe.Macro para iterar sobre un GList

Para ilustrar el problema: Por lo general escribo una gran cantidad de código que se parece a esto:

GList *list, *elem; 
MyType *item; 

for(elem = list; elem; elem = elem->next) { 
    item = elem->data; 
    /* do something with item */ 
} 

Con una macro que se puede reducir a

GList *list; 
MyType *item; 

GFOREACH(item, list) { 
    /* do something with item */ 
} 

que es mucho menos ruidoso.


Nota: Me di cuenta de que GLib proporciona una función foreach para iterar sobre una lista y llamar a una llamada de retorno para cada elemento, pero a menudo la vía indirecta de una devolución de llamada hace que el código sea más difícil de leer, especialmente si la devolución de llamada es solamente usado una vez.


Actualización: ya que no hay ninguna macro estándar, estoy poniendo la macro estoy usando aquí en caso de que sea de alguna utilidad para alguien más. Correcciones/mejoras son bienvenidas.

#define GFOREACH(item, list) for(GList *__glist = list; __glist && (item = __glist->data, true); __glist = __glist->next) 
+0

Estoy bastante seguro de que GLib solo proporciona las funciones foreach para iterar sobre sus diversas estructuras de datos. Estoy de acuerdo, no siempre es bueno para la legibilidad, aunque con un nombre descriptivo para la devolución de llamada generalmente me parece bien. – Cascabel

Respuesta

6

No hay tal macro.

Normalmente utilizo un bucle for como en su ejemplo a menos que la operación abarque más de, digamos, quince líneas, en cuyo caso generalmente encuentro que una función foreach adicional con un nombre descriptivo es más legible que la alternativa.

Lo que no se dan cuenta es que no necesariamente tiene que escribir su propia función foreach:

g_list_foreach(list, (GFunc)g_free, NULL); 

libera a cada elemento de la lista, una operación que utilizo a menudo.

+2

Nota: para liberar una lista, Glib ahora ofrece g_list_free_full(), http://developer.gnome.org/glib/2.28/glib-Doubly-Linked-Lists.html#g-list-free-full. Eso es probablemente más idiomático para liberar una lista completa (aunque supongo que hace lo mismo internamente). – sleske