1、
#define clr_red "\033[31m" /* 紅色字 */
#define clr_green "\033[32m" /* 綠色字 */
#define clr_yellow "\033[33m" /* 黃色字 */
#define clr_blue "\033[34m" /* 藍色字 */
#define clr_purple "\033[35m" /* 紫色字 */
#define clr_skyblue "\033[36m" /* 天藍字 */
#define clr_white "\033[37m" /* 白色字 */
#define clr_blk_wht "\033[40;37m" /* 黑底白字 */
#define clr_red_wht "\033[41;37m" /* 紅底白字 */
#define log_level_map(***) \
***(log_level_debug, "debug", clr_white) \
***(log_level_info, "info ", clr_green) \
***(log_level_warn, "warn ", clr_yellow) \
***(log_level_error, "error", clr_red) \
***(log_level_fatal, "fatal", clr_red_wht)
typedef enum log_level_e;
這個巨集的作用是在日誌中,對不同級別的日誌,選擇不同的顏色列印。上面的是表示顏色的巨集,很簡單。 關鍵是下面的log_level_map,這個巨集可以說是乙個二級巨集,不知道有沒有這個概念,因為它後面括號裡的內容,也是乙個巨集。看下面的用法,在log_level_map巨集的下面定義了乙個列舉,這個列舉表示告警的級別。在這個列舉的中,定義了另乙個巨集。先把log_level_map(***)的第一層巨集展開,是這樣的:
typedef enum log_level_e;
這裡為了看起來方便,把裡面的巨集定義取掉了。展開第一層後,***還是乙個巨集,在enum中定義的該巨集,所以需要繼續展開,根據第一段**中的巨集定義,展開後是這樣的:
typedef enum log_level_e;
這樣看起來就簡單多了,但這還不是全部。。。
第二個使用該巨集的地方:
const char* pcolor = "";
const char* plevel = "";
#define ***(id, str, clr) \
case id: plevel = str; pcolor = clr; break;
switch (level)
#undef ***
第一層展開後跟上面的是一樣的,主要就是第二層,這裡直接展開第二層:
switch (level)
是不是很簡單了,就是根據日誌級別,設定相應的資訊。當然,上面所有的巨集展開實際上都在一行,只不過我為了看起來簡單,分了行。
2、使用巨集實現類似於c++中容器的功能
在array.h和queue.h中,使用巨集定義實現了類似於vector和deque的功能。因為這兩個功能的實現方式差不多,而且理解起來很簡單,就不貼介面了,只看看結構體。
#define array_decl(type, atype) \
struct atype ; \
typedef struct atype atype;\
type就是容器中元素的型別,atype就是這個容器的型別。舉個程式中使用例子
array_decl(struct epoll_event, events)
這樣就定義了乙個容器,容器型別為events,成員型別為struct epoll_event,展開就是
struct events ;
功能挺強大,但理解起來挺簡單。當然了,比起c++標準庫的容器,用起來肯定還是麻煩一些。
3、使用巨集實現類似c++繼承的功能
#define htimer_fields \
hevent_fields \
uint32_t repeat; \
uint64_t next_timeout; \
struct heap_node node;
struct htimer_s ;
struct htimeout_s ;
struct hperiod_s ;
htimer_s、htimeout_s和hperiod_s都包含htimer_fields,就相當於這三個結構體「繼承」了同乙個「基類」,擁有共同的一些成員。但是我個人不喜歡這種方式,我寧願將該「基類」實現為乙個結構體,然後作為其他三個結構體的內部成員。我覺得使用」基類結構體「的方式比使用巨集更具意義,也更可讀。
先寫這麼多吧。。。
Swizzling 偷梁換柱的黑魔法!
我們知道,oc是一門動態執行時語言。我們也知道,oc中的函式呼叫本質上其實是訊息的傳送 objc msgsend someobject,selector methodname parameters 所有要呼叫的函式,編譯階段是無法確定的,只有到執行的時候才能確定!正因為有此特性,所以在執行階段,我們...
黑魔法 iOS鏈式程式設計
在使用sdautolayout 時就已經發現這種鏈式程式設計。通過 將屬性鏈結在一起形成如同一條鏈的程式設計方法。self.totalmoneycount sd layout.leftequaltoview self rightequaltoview self topspacetoview self...
Python黑魔法 元類
python黑魔法 元類 術語 元程式設計 指的是程式具有編寫或操縱其自身作為它們資料的潛力。python支援稱為元類的類的元程式設計。元類是乙個深奧的物件導向程式設計 oop 概念,隱藏在幾乎所有的python 之後。無論你是否意識到它的存在,你都一直在使用它們。大多數情況下,你並不需要了解它。而...