2009-10-23 25 views
10

Tôi đang sử dụng cấu trúc danh sách được liên kết kép của GLib, GList. Tôi muốn biết nếu có bất kỳ một macro tiêu chuẩn nào để lặp qua GList. Tôi không thể tìm thấy bất kỳ điều như vậy trong tài liệu GLib. Kết quả là tôi đã tạo macro của riêng mình, nhưng tôi muốn sử dụng một cái gì đó chuẩn nếu nó tồn tại.Macro để lặp qua GList

để minh họa cho vấn đề này: Thường thì tôi viết rất nhiều mã mà trông như thế này:

GList *list, *elem; 
MyType *item; 

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

Với một macro nó có thể được giảm xuống còn

GList *list; 
MyType *item; 

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

Đó là ít hơn nhiều ồn ào.


Lưu ý: Tôi nhận ra rằng GLib cung cấp một hàm foreach cho iterating trên một danh sách và kêu gọi một cuộc gọi lại cho mỗi phần tử, nhưng thường là gián tiếp của một callback làm cho mã khó đọc, đặc biệt là nếu gọi lại duy nhất là đã sử dụng một lần.


Cập nhật: khi không có macro chuẩn, tôi sẽ đặt macro mà tôi đang sử dụng ở đây trong trường hợp sử dụng cho người khác. Sửa chữa/cải tiến được hoan nghênh.

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

Tôi chắc chắn GLib chỉ cung cấp các chức năng foreach để lặp qua các cấu trúc dữ liệu khác nhau của nó. Tôi đồng ý, nó không phải luôn luôn tuyệt vời cho dễ đọc - mặc dù với một tên mô tả cho gọi lại nó thường có vẻ ổn với tôi. – Cascabel

Trả lời

6

Không có macro nào như vậy.

Tôi thường sử dụng vòng lặp for như trong ví dụ của mình trừ khi hoạt động kéo dài hơn mười lăm dòng, trong trường hợp này, tôi thường thấy rằng chức năng bổ sung foreach có tên mô tả dễ đọc hơn thay thế.

Những gì bạn có thể không nhận ra là bạn không nhất thiết phải viết chức năng của riêng bạn foreach:

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

giải phóng mỗi mục trong danh sách, một hoạt động mà tôi thường sử dụng.

+2

Lưu ý: Để giải phóng danh sách, Glib hiện cung cấp g_list_free_full(), http://developer.gnome.org/glib/2.28/glib-Doubly-Linked-Lists.html#g-list-free-full. Đó có lẽ là thành ngữ hơn để giải phóng một danh sách đầy đủ (mặc dù tôi đoán nó cũng làm điều tương tự). – sleske