2009-10-23 10 views
10

Używam podwójnie połączonej struktury GLib, GList. Chciałbym wiedzieć, czy istnieje jakieś standardowe standardowe makro do iteracji nad GList. Nie mogłem znaleźć czegoś takiego w dokumentacji GLib. W rezultacie stworzyłem własne makro, ale wolę używać czegoś standardowego, jeśli istnieje.Makro do iterowania nad GLISTEM

do zilustrowania problemu: Zazwyczaj piszę dużo kodu, który wygląda tak:

GList *list, *elem; 
MyType *item; 

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

Z makro może być zmniejszona do

GList *list; 
MyType *item; 

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

który jest znacznie mniej hałaśliwe.


Uwaga: zdałem sobie sprawę, że GLib dostarcza funkcji foreach do iteracji po liście i wywołaniem callback dla każdego elementu, ale często wskazanie pośrednie z zwrotnego sprawia, że ​​kod trudniejsze do odczytania, szczególnie jeśli zwrotna jest tylko użyty raz.


Aktualizacja: skoro nie ma standardowego makro, Kładę makro używam tu w przypadku, gdy jest ich wykorzystanie do kogoś innego. Korekty/poprawki są mile widziane.

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

Jestem całkiem pewna, że ​​GLib zapewnia tylko funkcje foreach do iteracji w różnych strukturach danych. Zgadzam się, to nie zawsze jest dobre dla czytelności - chociaż z opisową nazwą dla callback to zwykle wygląda dobrze dla mnie. – Cascabel

Odpowiedz

6

Nie ma takiego makro.

Zwykle używam pętli for, jak w twoim przykładzie, chyba że operacja obejmuje więcej niż, powiedzmy, piętnaście linii, w którym to przypadku zazwyczaj stwierdzam, że dodatkowa funkcja foreach z opisową nazwą jest bardziej czytelna niż alternatywa.

Co może nie zdaje sobie sprawy, że nie koniecznie trzeba napisać własną funkcję foreach:

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

uwalnia każdą pozycję na liście, operacji, które często używam.

+2

Uwaga: Aby zwolnić listę, Glib oferuje teraz g_list_free_full(), http://developer.gnome.org/glib/2.28/glib-Doubly-Linked-Lists.html#g-list-free-full. Prawdopodobnie jest to bardziej idiomatyczne, jeśli chodzi o zwalnianie pełnej listy (choć myślę, że robi to samo wewnętrznie). – sleske

Powiązane problemy