吐槽
- 2年前, 曾經(jīng)花費(fèi)了巨大的精力自學(xué)了c++, 從晦澀難懂的標(biāo)準(zhǔn)庫(kù)中學(xué)到了很多編程技巧(本人并不從事c++開發(fā))應(yīng)用到了項(xiàng)目中, 但強(qiáng)悍的泛型編程的思想以及技巧卻一直無(wú)法展現(xiàn)在自己的工作中(本人從事ios), 畢竟OC實(shí)現(xiàn)面向?qū)ο蟮募夹g(shù)(動(dòng)態(tài),多態(tài),反射)是和java一樣的底層機(jī)制(
small talk), 但卻和c++的虛函數(shù)是完全不同的,具體可以參考 泛型
- 泛型編程是c++的一座大山, 擋住了 95% 的程序員, 這其中的95%并不是說(shuō)市面是搞編程的人中只有5%在從事c++, 而是說(shuō)從事c++的人中, 絕大多數(shù)并不能發(fā)揮出c++最核心的泛型的威力, 因?yàn)榫褪聦?shí)而言, 復(fù)雜繁鎖只是一方面的原因, 另一方面是國(guó)內(nèi)的市場(chǎng)決定, 95%都是應(yīng)用類型的軟件, 項(xiàng)目中基本用不了泛型的技術(shù)
這篇文章也是兌現(xiàn)了3年前對(duì)自己的承諾(
當(dāng)時(shí)發(fā)表OC文章時(shí), 說(shuō)要抽時(shí)間寫一篇宏的文章)廢話不說(shuō)了, 進(jìn)入正題
C語(yǔ)言中的泛型思想
- c標(biāo)準(zhǔn)中有一個(gè)萬(wàn)能指針
void *, 這里不再闡述, 它的作用其實(shí)是針對(duì)運(yùn)行時(shí)來(lái)說(shuō)的, 并不在當(dāng)前的討論范圍, 嚴(yán)格來(lái)說(shuō)并不是c++中的靜態(tài)多態(tài)(當(dāng)然也叫泛型)
- 真正
長(zhǎng)的像c++中的泛型其實(shí)是#define, 在c98(記得好像是)中它有了可變參數(shù), 至于它的語(yǔ)法這里也不說(shuō)了, 在VC和gcc下對(duì)于define的實(shí)現(xiàn)在展開格式上會(huì)有些編譯區(qū)別, 這導(dǎo)致了在使用上有了巨大的差異, 這里要討論的是gcc下的宏, 所以相當(dāng)于GNUC下的方言C, 配合GCC下的方言語(yǔ)法宏實(shí)現(xiàn)出了逆天的功能
回顧
這里就不再細(xì)說(shuō)c++泛型相關(guān)的知識(shí), 也不描述gcc下宏的方言, 具體看本人倉(cāng)庫(kù)cpp相關(guān)的部分
重頭戲(ios)
利用宏簡(jiǎn)化惡心的ios代碼
- OC的語(yǔ)法向來(lái)是特立獨(dú)行的, 和其他語(yǔ)言的代碼風(fēng)格完全不同, 所以別的程序員對(duì)我們這們語(yǔ)言的第1反應(yīng)是
傻雕語(yǔ)言, 但說(shuō)實(shí)話本人還惡心java那種點(diǎn)來(lái)點(diǎn)去的語(yǔ)言
UIView* v = [UIView new];
//COLOR是自己定義的宏, 這里就不說(shuō)了
[v setBackgroundColor:COLOR(ff0000)];
[v setFrame:CGReckMake(100,100,100,100)]
[self.view addSubview:v];
- 可能OC之父也想迎合大眾語(yǔ)法, 所以提供了
getter,setter的簡(jiǎn)化版本
UIView* v = [UIView new];
v.backgroundColor = COLOR(ff0000);
v.frame = CGRectMake(100,100,100,100)
[self.view addSubview:v];
這樣寫比較人性化, 別家的程序員也能看懂, 但若是涉及到多參時(shí), 還是要寫完整的語(yǔ)法
[btn setTitle:@"我是二狗" forState:1<<2];
[btn setTitle:@"我是癟三" forState:0];
別家的代碼可能是這樣的優(yōu)雅人性(
如安卓)
view.setText("我是安卓小屁孩", normal);
view.setText("我是安卓狗蛋", select);
// 這里是瞎寫的
所以O(shè)C 2.0出現(xiàn)了block(
也就是函數(shù)指針), 各路大神發(fā)表了各種框架,學(xué)著java的點(diǎn)語(yǔ)法鏈?zhǔn)?/code>
[v mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.offset(100);
make.width.height.equalTo(@100);
}];
這種用block做成的鏈?zhǔn)骄幊? 我想是個(gè)人都會(huì)寫, 其實(shí)也沒多大技術(shù)含量, 從效率上來(lái)講,增加了運(yùn)行過(guò)程中的
函數(shù)調(diào)用開銷, 而且從本質(zhì)上來(lái)講,只是所謂的寫的方便,在內(nèi)部還是調(diào)用了原生的語(yǔ)法, 不同類型無(wú)法用統(tǒng)一的書寫格式,必須要定義自己的一套, 當(dāng)然優(yōu)點(diǎn)是大大簡(jiǎn)化了api的調(diào)用
但說(shuō)實(shí)話, 這并不是所謂的創(chuàng)新, 只是和市面上95%的程序員一樣的慣性思維
推導(dǎo)
想實(shí)現(xiàn)的書寫格式
UILable* lab = [UILabel new];
lab.set(backgroundColor, COLOR(ff0000)
.set(text,@"我是二狗")
.set(font,Font(14)
.set(textColor, COLOL(00ff00));
上面是想實(shí)現(xiàn)的書寫格式, 看起來(lái)是
只有一個(gè)方法set
- 傳遞的
第1個(gè)參數(shù)是枚舉, 用來(lái)識(shí)別動(dòng)作 - 傳遞的
第2個(gè)參數(shù)是值, 用來(lái)賦值
可以用block來(lái)封裝, 但
set這個(gè)函數(shù)的第2個(gè)參數(shù)不能統(tǒng)一, 因?yàn)橛械目赡軅鬟f對(duì)象, 有的可能傳遞簡(jiǎn)單類型, 所以一般封裝方案是將set的第2個(gè)參數(shù)設(shè)置id, 內(nèi)部再轉(zhuǎn)換
這是很慣性的思路, 沒有問題
思考
- 觀察其實(shí)最后本質(zhì)上的代碼這樣的
UILabel* lab = [UILabel new];
[lab setBackgroundColor:COLOR(ff0000)];
[lab setText:@"二狗"];
[lab setFont:Font(14)];
[lab setTextColor:xxx];
這明顯的可以用宏來(lái)定義這些操作
#define set(_op, _val) set##_op:(_val)
但這個(gè)宏展開后, 沒法書寫出
[lab, 這幾個(gè)字符, 也就沒用, 所以要換個(gè)想法, 假設(shè)已經(jīng) 創(chuàng)建好了lab這個(gè)變量
#define set(_op, _val) [lab set##_op:(_val)]
UILabel* lab = [UILabel new];
set(Text, @"二狗");
這里發(fā)現(xiàn)
這樣寫不是很傻逼嗎
- 不能
鏈?zhǔn)?/code>- 不能
點(diǎn)
其實(shí)不要忘了編譯器特性
#define set(_op, _val) lab._op = _val
UILabel* lab = [UILabel new];
set(next, @"二狗"); //注意這里是小寫
上面只解決了點(diǎn), 但說(shuō)實(shí)話, 個(gè)人喜歡
標(biāo)準(zhǔn)的[], 因?yàn)?code>點(diǎn)語(yǔ)法最終還是會(huì)轉(zhuǎn)換為[], 鏈?zhǔn)骄蜎]法了, 繼續(xù)推導(dǎo):
#define lab() UILabel* lab = [UILable new]; lab
#define set(_op, _val) self, [lab set##_op:(_val)], lab
lab().set(Text,@"二狗");
會(huì)被編譯成
UILabel* lab = [UILabel new]; lab.self, [lab setText:@"二狗"], lab;
編譯器會(huì)將宏展開到
一行顯示, 并且調(diào)用的是原生的代碼, 沒有一點(diǎn)多余的runtime, 并且會(huì)類型檢查
但有個(gè)問題就是
- 編譯器報(bào)警告
未使用的lab, 就是最后的, lab;
- 這種警告解決方案有很多, 可以配置編譯警告, 這里就不說(shuō)了
- 上下文中不能再現(xiàn)出
lab這個(gè)變量
- 解決也簡(jiǎn)單, 添加作用域
{}PS: 這里要說(shuō)明一點(diǎn), 任何OC對(duì)象都可以調(diào)用
xxx.self
__unused UILabel* lab = ({
lab().set(Text,@"二狗");
});
這里利用了
gcc方言 ({}), 這個(gè)語(yǔ)法就是徹底改變UIView布局的核心,__unused是屏蔽未使用lab的警告
簡(jiǎn)化版本1
需要說(shuō)明的是本人使用的布局框架是
MyLayout
定義布局
#define $w(_w) myWidth = (_w), layout
#define $h(_h) myHeight = (_h), layout
#define $l(_l) myLeft = (_l), layout
#define $r(_r) myRight = (_r), layout
#define $t(_t) myTop = (_t), layout
#define $b(_b) myBottom = (_b), layout
#define $hm(_hm) myHorzMargin = (_hm), layout
#define $hs(_hs) subviewHSpace = (_hs), layout
#define $vs(_vs) subviewVSpace = (_vs), layout
#define $p(_t, _l, _b, _r) padding = (UIEdgeInsets){(_t), (_l), (_b), (_r)}, layout
#define $g(_g) gravity = (_g), layout
#define $W(_W) wrapContentWidth = (_W), layout
#define $H(_H) wrapContentHeight = (_H), layout
#define $we(_we) weight = (_we), layout
至于這個(gè)框架的使用, 這里不詳談
之所以用$, 為了避免和程序中的其他變量重名
定義UILabel
#define $label \
UILabel* layout = [UILabel new]; \
layout
#define $ltle(_txt) text = (_txt), layout
#define $lalign(_align) textAlignment = (_align), layout
#define $lcolor(_c) textColor = (_c), layout
#define $llines(_n) numberOfLines = (_n), layout
__unused UILabel* lab = ({
$label
.$ltel(@"二狗")
.$lcolor(COLOR(ff0000));
});
case_1
__unused UILabel* grp_name_lab = ({
$label
.$lcolor(COLOR(333333))
.$lalign(1)
.$llines(1)
.$W(true)
.$H(true)
.$font(SystemFont(14))
.$t(8)
.alignment = MyGravity_Horz_Center;
layout;
});
[self.view addSubview:grp_name_lab];
以上這種書寫, 要定義
UILabelUIButton等各自的一套, 不能統(tǒng)一, 但也大簡(jiǎn)化了api的調(diào)用, 并且完全是利用了編譯特性, 其實(shí)它還可以繼續(xù)簡(jiǎn)化, 就是定義出常用的label為宏
簡(jiǎn)化版本2
版本1其實(shí)是最簡(jiǎn)單的宏的用法
- 缺點(diǎn)是每種類型的(
eg:UILabe, UIButton)都要寫自己的一套所以版本2的目的是
抽象一個(gè)統(tǒng)一設(shè)置屬性的語(yǔ)法出來(lái)
抽象對(duì)象的創(chuàng)建
#define $V_ARG_LST_1 1
#define $V_ARG_LST_2 2, 1
#define $V_ARG_LST_3 3, 2, 1
#define $V_ARG_LST_4 4, 3, 2, 1
#define $V_ARG_LST_5 5, 4, 3, 2, 1
#define $V_ARG_LST_6 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_7 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_8 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_9 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_10 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_11 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_12 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_13 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_14 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_ARG_LST_15 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $V_MAX_ARG (15)
/// !!!: 構(gòu)建view --start
/** 最簡(jiǎn)單的創(chuàng)建view */
#define $_1(__v_type) \
__unused __v_type* layout = ({ \
__v_type* view = [_CLS(__v_type) new]; \
view; \
}); layout \
/** 通過(guò)一個(gè)存在的變量構(gòu)造出 統(tǒng)一格式的layout */
#define $_2(__v_type, ...) \
__v_type* layout = ({(__v_type*)__VA_ARGS__;});layout
#define $V_FUN(_idx,...) $_##_idx
#define $V_FUN_IDX( _0, _1, _2, _3, _4, _5, \
_6, _7, _8, _9, _10, \
_11, _12, _13, _14, ...) \
$V_FUN(__VA_ARGS__)
#define $V_ARG(_N,...) \
$V_FUN_IDX(__VA_ARGS__, $V_ARG_LST_15)
#define $(...) \
$V_ARG($V_MAX_ARG, __VA_ARGS__, $V_ARG_LST_15)(__VA_ARGS__)
這里不解釋了(
可變參數(shù)宏的高級(jí)運(yùn)用), 作用有2個(gè):
- 創(chuàng)建一個(gè)新的對(duì)象,對(duì)象的類型自己指定, 并且統(tǒng)一對(duì)象名為通用的`layout
- 也可以調(diào)用2參數(shù)的宏, 將當(dāng)前存在的對(duì)象
別名出一個(gè)通用的layout使用如下:
// 格式1: 創(chuàng)建view
__unused UILabel* lab = ({
$(UILabel)
.$font(Font(13))
.$ltle(@"二狗");
});
UILabel* lab_2 = [UILabel new];
{
$(UILabel, lab_2).$xx(xx)....
}
其實(shí)這里和版本1沒撒區(qū)別, 但有一點(diǎn), 類型可以自己指定
統(tǒng)一屬性設(shè)置
// 變量_val已經(jīng)賦值
#define $set_1(_val) \
self, [layout s##_val:(_val)];layout
// 指定值(但不指定 類型)
#define $set_2(_mid,...) \
self, [layout s##_mid:(__VA_ARGS__)];layout
// 指定變量名 并且 指定類型
#define $set_3(_v_type, _mid, ...) \
self, [((_v_type)layout) s##_mid:(__VA_ARGS__)];((_v_type)layout)
#define $SET_FUN(_idx,...) $set_##_idx
#define $SET_FUN_IDX( _0, _1, _2, _3, _4, _5, \
_6, _7, _8, _9, _10, \
_11, _12, _13, _14, ...) \
$SET_FUN(__VA_ARGS__)
#define $SET_ARG(_N,...) \
$SET_FUN_IDX(__VA_ARGS__, $V_ARG_LST_15)
/// !!!: 通過(guò)變量賦值
#define $set(...) \
$SET_ARG($V_MAX_ARG, __VA_ARGS__, $V_ARG_LST_15)(__VA_ARGS__)
這里用
可變宏設(shè)計(jì)出一個(gè)通用的set
這里set共有3種格式
1參數(shù),2參數(shù),3參數(shù)
1參數(shù)
根據(jù)很明顯, 必須要有1個(gè)變量名為
etXxx開頭的變量
NSString* etText = @"二狗";
$(UILabel).$set(etText); //會(huì)被編譯成 setText:etText
2參數(shù)
很容易看明白, 使用如下:
$(UILabel)
.$set(etBackgroundColor,[COLOR(0) colorWithAlphaComponent:.3])
.$set(etText, @"二狗");
這種情況下, 其實(shí)沒有用到
etText這種變量, 但若有etText這個(gè)變量,則它會(huì)變色, 看起來(lái)更舒服
3參數(shù)
這種情況下先不說(shuō), 后面再說(shuō)
定義一些全局性的必要變量
如 etText這些UIView中常用的
.h文件
#if __OBJC__
#define $LB_UI_EXTERN(_) \
_(UIColor*, BackgroundColor) \
_(CGFloat, CornerRadius) \
_(bool, ClipsToBounds) \
_(CGFloat, Alpha) \
_(bool, Opaque) \
_(bool, Hidden) \
_(UIViewContentMode,ContentMode) \
_(bool, UserInteractionEnabled) \
_(NSInteger, Tag) \
_(MyVisibility, Visibility) \
\
\
_(MyOrientation, Orientation) \
\
\
_(NSString*, Text) \
_(UIColor*, TextColor) \
_(NSTextAlignment, TextAlignment) \
_(UIFont*, Font) \
_(NSAttributedString*,AttributedText) \
_(NSInteger, NumberOfLines) \
\
\
_(bool, Enabled) \
_(bool, Selected) \
\
\
_(NSString*, Title) \
_(CGSize, ImageSize) \
_(CGFloat, Spacing) \
_(NSMButtonImagePosition, ImagePosition) \
_(NSString*, LbTleNor) \
_(NSString*, LbTleSEL) \
_(NSString*, LbTleHig) \
_(UIColor*, LbTleColorNor) \
_(UIColor*, LbTleColorSel) \
_(UIColor*, LbTleColorHig) \
_(UIImage*, LbImgNor) \
_(UIImage*, LbImgSel) \
_(UIImage*, LbImgHig) \
_(UIImage*, LbBgIconNor) \
_(UIImage*, LbBgIconSel) \
_(UIImage*, LbBgIconHig) \
_(UIFont*, LbBtnFont) \
_(UIViewContentMode,LbBtnIconMode) \
_(NSInteger, LbLines) \
\
_(UIImage*, Image) \
\
\
_(CGFloat, MyHorzMargin) \
_(CGFloat, MyWidth) \
_(CGFloat, MyHeight) \
_(CGFloat, MyLeft) \
_(CGFloat, MyRight) \
_(CGFloat, MyTop) \
_(CGFloat, MyBottom) \
_(MyGravity, Alignment) \
_(bool, UseFrame) \
\
\
_(CGFloat, PaddingTop) \
_(CGFloat, PaddingLeft) \
_(CGFloat, PaddingRight) \
_(CGFloat, PaddingBottom) \
_(UIEdgeInsets, Padding) \
_(MyGravity, Gravity) \
_(CGFloat, SubviewSpace) \
_(CGFloat, SubviewHSpace) \
_(CGFloat, SubviewVSpace) \
_(bool, WrapContentSize) \
_(bool, WrapContentWidth) \
_(bool, WrapContentHeight) \
_(CGFloat, Weight) \
#define $LB_UI_MAKE_EXTERN(__type__,__name__) extern __type__ et##__name__;
// !!!: 生成extern
$LB_UI_EXTERN($LB_UI_MAKE_EXTERN)
這里又是宏的高級(jí)運(yùn)用, VC中的宏是不行的
.m文件
#define $LB_UI_MAKE_VAR(_v_type, __name) _v_type et##__name;
// 生成全局變量
$LB_UI_EXTERN($LB_UI_MAKE_VAR);
在.h中, 只用寫一遍要用的變量, 然后
extern 以及 變量的初始化都只需要對(duì)應(yīng)的宏展開就行了
簡(jiǎn)化UIView
上述創(chuàng)建
UILabel等都要每次都寫一遍(你可用xcode的代碼生成器簡(jiǎn)化一些)
所以完全可以再用一層宏, 來(lái)預(yù)定義一些樣式, 反正定義出來(lái)的宏, 又不占據(jù)調(diào)用時(shí)間, 不用的話編譯器就不用生成, 相當(dāng)于沒寫
#define $sty_hm_15() $hm(15)
#define $sty_hm_10() $hm(10)
#define $sty_p_10() $p(10,10,10,10)
#define $sty_p_15() $p(15,15,15,15)
#define $sty_p_20() $p(20,20,20,20)
#define $sty_g_c() $g(MyGravity_Center)
#define $sty_g_hc() $g(MyGravity_Horz_Center)
#define $sty_g_hf() $g(MyGravity_Horz_Fill)
#define $sty_g_ha() $g(MyGravity_Horz_Among)
#define $sty_g_hbw() $g(MyGravity_Horz_Between)
#define $sty_g_vc() $g(MyGravity_Vert_Center)
#define $sty_g_vf() $g(MyGravity_Vert_Fill)
#define $sty_g_va() $g(MyGravity_Vert_Among)
#define $sty_g_vbw() $g(MyGravity_Vert_Between)
/**
hm->指定
*/
#define $vauto(_hm) $ver.$H(true).$W(0).$bgcolor(CLEAR_COLOR).$hm(_hm)
/**
size == auto, 垂直居中
*/
#define $hauto() $line.$W(true).$H(true).$bgcolor(CLEAR_COLOR).$sty_g_vc()
/**
在布局視圖,
h->auto
hm -> _space
v->center
*/
#define $h_hm(_space) $hauto().$W(0).$hm(_space)
/** 在布局視圖中
we->1
h->auto
v->center
*/
#define $h_we() $hauto().$W(0).$we(1)
/**
h->auto,
w->auto
font->14
color->333
*/
#define $lab(_tle) $label.$W(true).$H(true).$font(SystemFont(14)).$lcolor(COLOR(333333)).$ltle(_tle)
/** h->auto
w->auto
font->12
color->999
*/
#define $lab_small(_tle) $lab(_tle).$font(SystemFont(12)).$lcolor(COLOR(999999))
/**
h->auto
w->auto
font->b18
color->333
*/
#define $lab_big(_tle) $lab(_tle).$font(BoldSystemFont(18))
#define $button(_tle) $btn.$btle(_tle,0).$bfont(SystemFont(14)).$btlecolor(COLOR(333333),0).$W(true).$H(true)
/** image相關(guān) */
#define $iv_img(_img,_w,_h) $(NSMImageView).$set(etImage, (_img)).$set(etMyWidth,(_w)).$set(etMyHeight,(_h)).$set(etContentMode,2)
/** flow */
#define $flw(_num) __unused MyFlowLayout* layout = [MyFlowLayout flowLayoutWithOrientation:(0) arrangedCount:(_num)]; layout
#define $vflow(_num,_hs,_vs) $flw((_num)).$g(MyGravity_Horz_Fill).$hs((_hs)).$vs((_vs)).$H(true)
/** float */
#define $vfla() __unused MyFloatLayout* fl = [MyFloatLayout floatLayoutWithOrientation:0]; layout
#define $vfloat(_hs, _vs) $fla().$hs((_hs)).$vs((_vs))
/// !!!: 以下這幾個(gè)宏建議不要再用了
#define $lab_f_14() $label.$set(etFont, SystemFont(14)).$cset($$CLR_LAB_0xf).$W(true).$H(true)
#define $lab_3_14() $label.$set(etFont, SystemFont(14)).$cset($$CLR_LAB_0x333).$W(true).$H(true)
#define $lab_6_14() $label.$set(etFont, SystemFont(14)).$cset($$CLR_LAB_0x666).$W(true).$H(true)
#define $lab_9_14() $label.$set(etFont, SystemFont(14)).$cset($$CLR_LAB_0x999).$W(true).$H(true)
/** 寬高auto, 顏色為333 */
#define $btn_fff(_img, _font, _tle) $btn.$cset($$CLR_BTN_NOR_0xf).$set(etLbTleNor,(_tle)).$set(etLbImgNor,(_img)).$set(etLbBtnFont, (_font)).$W(true).$H(true)
#define $btn_333(_img, _font, _tle) $btn.$cset($$CLR_BTN_NOR_0x333).$set(etLbTleNor,(_tle)).$set(etLbImgNor,(_img)).$set(etLbBtnFont, (_font)).$W(true).$H(true)
#define $btn_666(_img, _font, _tle) $btn.$cset($$CLR_BTN_NOR_0x666).$set(etLbTleNor,(_tle)).$set(etLbImgNor,(_img)).$set(etLbBtnFont, (_font)).$W(true).$H(true)
#define $btn_999(_img, _font, _tle) $btn.$cset($$CLR_BTN_NOR_0x999).$set(etLbTleNor,(_tle)).$set(etLbImgNor,(_img)).$set(etLbBtnFont, (_font)).$W(true).$H(true)
使用
$hauto().$hs(5); //自己體會(huì)
整體一起來(lái)
定義幾個(gè)宏, 它們的作用自己體會(huì)
// !!!: 掛載
//當(dāng)前作用域下的 layout掛載到當(dāng)前 正在寫代碼的這個(gè)類的當(dāng)前對(duì)象self中(setter)
#define $mount(_key) self; [self set##_key:layout]; layout
// !!!: 指定當(dāng)前l(fā)ayout的父view
#define $super(_v) \
self, [(_v) addSubview:layout], layout
// !!!: 當(dāng)前l(fā)ayout指定添加一個(gè)子view
#define $add(_sub_v) \
self,[layout addSubview:(_sub_v)], layout
// !!!: 尋找子view
/// 在當(dāng)前l(fā)ayout中根據(jù)指定的tag找到它的子view
/// 這個(gè)會(huì)將當(dāng)前的layout重新賦值到找到的子view, 若沒有找到, 則layout就為nil了, 就芭比Q了
/// 找到后, 后續(xù)的layout其實(shí)已經(jīng)變了, 若想setter, 則調(diào)用 3個(gè)參數(shù)的 $set, 指定類型(第1個(gè)參數(shù))
#define $get(_tag) \
self, layout = (typeof(layout))[layout viewWithTag:(_tag)], layout
// !!!: 重新獲取頂層的 layout
#define $root(_super, _tag) self, layout = [(_super) viewWithTag:(_tag)], layout
// 為當(dāng)前的layout設(shè)置一個(gè) 別名
#define $alias(_type, _ov, _nv) self; __unused _type _nv = ({(_type)_ov;}); layout
// !!!: 執(zhí)行一段代碼
// eg: $(UIView).$exs{
// ... code
// }$exe();
// exs ===> excute start 代碼開始
// exe ===> excute_ended 代碼結(jié)束
#define $exs self, (
#define $exe() ), layout
使用
$hauto().$hs(5)
.$add(({
$btn_fff(IMAGE(user-ined-lw-gold), SystemFont(11), subar[index]).$H(false).$h(16).$W(0).$w(45);
ViewCorner(layout, 8);
layout;
}))
.$add({
$lab_f_14().$set(etFont,SystemFont(11)).$ltle(array[index]).$cset($$V_TAG_1971);
})
.$add(({
$iv_img(IMAGE(newcenter_img_jt), 8, 8);
}))
.$set(etBackgroundColor,[COLOR(0) colorWithAlphaComponent:.3])
.$H(0).$h(20).$corner(10).$set(etClipsToBounds, true).$super(tmp_v);
就這么簡(jiǎn)單, 這些宏完全可以再由自己去擴(kuò)展, 去簡(jiǎn)化, 去重命名
全部是在編譯時(shí), 由編譯器推導(dǎo)出來(lái), 并且全部是原生的方法, 效率沒的說(shuō)
在C語(yǔ)言中做出tuple
構(gòu)造tuple的結(jié)構(gòu)
#define $TUPLE_ARG_LST_1 1,1
#define $TUPLE_ARG_LST_2 2,2, 1,1
#define $TUPLE_ARG_LST_3 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_4 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_5 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_6 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_7 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_8 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_9 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_10 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_11 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_12 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_13 13,13, 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_14 14,14, 13,13, 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_15 15,15, 14,14, 13,13, 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_MAX_ARG (30)
#define $tuple_def_1(_name, _val, ...) \
struct{ \
typeof(_val) _name; \
};
// 如果注釋下面的, 打開這個(gè), 則編譯器生成的結(jié)構(gòu)
///// 是類與類之間組合的結(jié)構(gòu), 自己可以打開這個(gè),注釋下面的然后編譯試一試
//#define $tuple_def_2(_name, _val, ...) \
// $tuple_def_1(__VA_ARGS__) \
// struct{ \
// typeof(_val) _name; \
// };
#define $tuple_def_2(_name, _val, ...) \
struct{ \
$tuple_def_1(__VA_ARGS__) \
typeof(_val) _name; \
};
#define $TUPLE_FUN(_idx,...) $tuple_def_##_idx
#define $TUPLE_FUN_IDX( _0,_1, \
_2,_3, \
_4,_5, \
_6,_7, \
_8,_9, \
_10,_11, \
_12,_13, \
_14,_15, \
_16,_17, \
_18,_19, \
_20,_21, \
_22,_23, \
_24,_25, \
_26,_27, \
_28,_29, \
...) \
$TUPLE_FUN(__VA_ARGS__)
#define $TUPLE_ARG(_N,...) \
$TUPLE_FUN_IDX(__VA_ARGS__, $TUPLE_ARG_LST_15)
#define $tuple(_var, ...) \
struct{ \
$TUPLE_ARG($TUPLE_MAX_ARG,__VA_ARGS__, $TUPLE_ARG_LST_15)(__VA_ARGS__) \
}__unused _var
$tuple(aaa,age,10); //__code_1
__code_1會(huì)被編譯成 :
struct{
struct{
struct{
typeof(20.) money;
};
typeof(10) age;
};
}__attribute__((__unused__)) aaa;
格式完全和tuple一致
真正的tuple(同時(shí)賦值)
#define $TUPLE_ARG_LST_1 1,1
#define $TUPLE_ARG_LST_2 2,2, 1,1
#define $TUPLE_ARG_LST_3 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_4 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_5 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_6 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_7 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_8 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_9 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_10 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_11 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_12 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_13 13,13, 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_14 14,14, 13,13, 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_ARG_LST_15 15,15, 14,14, 13,13, 12,12, 11,11, 10,10, 9,9, 8,8, 7,7, 6,6, 5,5, 4,4, 3,3, 2,2, 1,1
#define $TUPLE_MAX_ARG (30)
#define $tuple_def_1(_name, _val) \
struct{ \
typeof(_val) _name; \
};
//#define $tuple_def_2(_name, _val, ...) \
// $tuple_def_1(__VA_ARGS__) \
// struct{ \
// typeof(_val) _name; \
// };
#define $tuple_def_2(_name, _val, ...) \
struct{ \
$tuple_def_1(__VA_ARGS__) \
typeof(_val) _name; \
};
#define $TUPLE_FUN(_idx,...) $tuple_def_##_idx
#define $TUPLE_FUN_IDX( _0,_1, \
_2,_3, \
_4,_5, \
_6,_7, \
_8,_9, \
_10,_11, \
_12,_13, \
_14,_15, \
_16,_17, \
_18,_19, \
_20,_21, \
_22,_23, \
_24,_25, \
_26,_27, \
_28,_29, \
...) \
$TUPLE_FUN(__VA_ARGS__)
#define $TUPLE_ARG(_N,...) \
$TUPLE_FUN_IDX(__VA_ARGS__, $TUPLE_ARG_LST_15)
#define $tuple_set_1(_name,_val,...) \
._name = (_val)
#define $tuple_set_2(_name,_val, ...) \
$tuple_set_1(__VA_ARGS__), \
._name = (_val) \
#define $TUPLE_SET_FUN(_idx,...) $tuple_set_##_idx
#define $TUPLE_SET_FUN_IDX( \
_0,_1, \
_2,_3, \
_4,_5, \
_6,_7, \
_8,_9, \
_10,_11, \
_12,_13, \
_14,_15, \
_16,_17, \
_18,_19, \
_20,_21, \
_22,_23, \
_24,_25, \
_26,_27, \
_28,_29, \
...) \
$TUPLE_SET_FUN(__VA_ARGS__)
#define $TUPLE_SET_ARG(_N,...) \
$TUPLE_SET_FUN_IDX(__VA_ARGS__, $TUPLE_ARG_LST_15)
#define $tuple_set(...) = { \
$TUPLE_SET_ARG($TUPLE_MAX_ARG,__VA_ARGS__, $TUPLE_ARG_LST_15)(__VA_ARGS__) \
}
#define $tuple(_var, ...) \
struct{ \
$TUPLE_ARG($TUPLE_MAX_ARG,__VA_ARGS__, $TUPLE_ARG_LST_15)(__VA_ARGS__) \
}__unused _var $tuple_set(__VA_ARGS__)
$tuple(aaa,age,10,money, 20.);
編譯器會(huì)編譯成
struct{
struct{
struct{
typeof(20.) money;
};
typeof(10) age; };
}__attribute__((__unused__)) aaa = {
.money = (20.),
.age = (10)
};
這種tuple, 在構(gòu)造結(jié)構(gòu)體時(shí),
類的層次結(jié)構(gòu)和c++中的tuple繼承體系結(jié)構(gòu)是一樣的, 但是tuple的取值有問題, 因?yàn)樵跁鴮憰r(shí), 先寫的10, 再寫的20, 在tuple中取值的順序應(yīng)該是get<0> 對(duì)應(yīng)的是10, get<1>對(duì)應(yīng)的是20,但最后賦值時(shí)順序卻是 第0個(gè)對(duì)應(yīng)-->20, 第1個(gè)對(duì)應(yīng)-->10, 但這種不用考慮, 因?yàn)橹付俗兞棵? 下面是真正意義上的tuple
真正的tuple
以下這些宏, 是真正在C語(yǔ)言中實(shí)現(xiàn)了tuple, 其中對(duì)宏的運(yùn)用已經(jīng)到了出神入化的境界了
#define $TUPLE_ARG_LST_1 1
#define $TUPLE_ARG_LST_2 2, 1
#define $TUPLE_ARG_LST_3 3, 2, 1
#define $TUPLE_ARG_LST_4 4, 3, 2, 1
#define $TUPLE_ARG_LST_5 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_6 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_7 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_8 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_9 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_10 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_11 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_12 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_13 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_14 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_ARG_LST_15 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1
#define $TUPLE_MAX_ARG (15)
#define $TUPLE_SET_FUN_NUM(_idx,...) $$_##_idx
#define $TUPLE_SET_FUN_IDX_NUM( \
_0,_1, \
_2,_3, \
_4,_5, \
_6,_7, \
_8,_9, \
_10,_11, \
_12,_13, \
_14, \
...) \
$TUPLE_SET_FUN_NUM(__VA_ARGS__)
// !!!: tuple 定義
#define $tuple_def_1(_val, _num, ...) \
struct{ \
typeof(_val) _num; \
}
#define $tuple_def_2(_v1, _v2, _n1, _n2, ...) \
struct{ \
$tuple_def_1(_v2, _n2); \
typeof(_v1) _n1; \
}
#define $tuple_def_3( \
_v1, _v2, _v3, _n1, _n2, _n3, ...) \
struct{ \
$tuple_def_2(_v2, _v3, _n2, _n3); \
typeof(_v1) _n1; \
}
#define $tuple_def_4( \
_v1, _v2, _v3, \
_v4, \
_n1, _n2, _n3, \
_n4,...) \
struct{ \
$tuple_def_3( \
_v2, _v3, _v4, \
_n2, _n3, _n4 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_5( \
_v1, _v2, _v3, \
_v4, _v5, \
_n1, _n2, _n3, \
_n4, _n5,...) \
struct{ \
$tuple_def_4( \
_v2, _v3, _v4, \
_v5, \
_n2, _n3, _n4, \
_n5 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_6( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_n1, _n2, _n3, \
_n4, _n5, _n6,...) \
struct{ \
$tuple_def_5( \
_v2, _v3, _v4, \
_v5, _v6, \
_n2, _n3, _n4, \
_n5, _n6 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_7( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, ...) \
struct{ \
$tuple_def_6( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_n2, _n3, _n4, \
_n5, _n6, _n7 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_8( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, ...) \
struct{ \
$tuple_def_7( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_9( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, ...) \
struct{ \
$tuple_def_8( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_10( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_v10, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, \
_n10, ...) \
struct{ \
$tuple_def_9( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, _v10, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9, _n10 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_11( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_v10,_v11, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, \
_n10, _n11,...) \
struct{ \
$tuple_def_10( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, _v10, \
_v11, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9, _n10, \
_n11 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_12( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_v10,_v11,_v12, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, \
_n10, _n11, _n12,...) \
struct{ \
$tuple_def_11( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, _v10, \
_v11,_v12, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9, _n10, \
_n11, _n12 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_13( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_v10,_v11,_v12, \
_v13, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, \
_n10, _n11, _n12, \
_n13, ...) \
struct{ \
$tuple_def_12( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, _v10, \
_v11,_v12,_v13, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9, _n10, \
_n11, _n12,_n13 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_14( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_v10,_v11,_v12, \
_v13, _v14, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, \
_n10, _n11, _n12, \
_n13, _n14, ...) \
struct{ \
$tuple_def_13( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, _v10, \
_v11,_v12,_v13, \
_v14, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9, _n10, \
_n11, _n12,_n13, \
_n14 \
); \
typeof(_v1) _n1; \
}
#define $tuple_def_15( \
_v1, _v2, _v3, \
_v4, _v5, _v6, \
_v7, _v8, _v9, \
_v10,_v11,_v12, \
_v13, _v14, _v15, \
_n1, _n2, _n3, \
_n4, _n5, _n6, \
_n7, _n8, _n9, \
_n10, _n11, _n12, \
_n13, _n14, _n15, ...) \
struct{ \
$tuple_def_14( \
_v2, _v3, _v4, \
_v5, _v6, _v7, \
_v8, _v9, _v10, \
_v11,_v12,_v13, \
_v14,_v15, \
_n2, _n3, _n4, \
_n5, _n6, _n7, \
_n8, _n9, _n10, \
_n11, _n12,_n13, \
_n14, _n15 \
); \
typeof(_v1) _n1; \
}
#define $TUPLE_FUN(_idx,...) $tuple_def_##_idx
#define $TUPLE_FUN_IDX( \
_0,_1, \
_2,_3, \
_4,_5, \
_6,_7, \
_8,_9, \
_10,_11, \
_12,_13, \
_14, \
...) \
$TUPLE_FUN(__VA_ARGS__)
#define $TUPLE_ARG(_N,...) \
$TUPLE_FUN_IDX(__VA_ARGS__, $TUPLE_ARG_LST_15)
// !!!: tuple同時(shí)賦值
#define $tuple_set_1(_val,...) \
(_val)
#define $tuple_set_2(_val, ...) \
$tuple_set_1(__VA_ARGS__), \
(_val) \
#define $tuple_set_3(_val, ...) \
$tuple_set_2(__VA_ARGS__), \
(_val)
#define $tuple_set_4(_val, ...) \
$tuple_set_3(__VA_ARGS__), \
(_val)
#define $tuple_set_5(_val, ...) \
$tuple_set_4(__VA_ARGS__), \
(_val)
#define $tuple_set_6(_val, ...) \
$tuple_set_5(__VA_ARGS__), \
(_val)
#define $tuple_set_7(_val, ...) \
$tuple_set_6(__VA_ARGS__), \
(_val)
#define $tuple_set_8(_val, ...) \
$tuple_set_7(__VA_ARGS__), \
(_val)
#define $tuple_set_9(_val, ...) \
$tuple_set_8(__VA_ARGS__), \
(_val)
#define $tuple_set_10(_val, ...) \
$tuple_set_9(__VA_ARGS__), \
(_val)
#define $tuple_set_11(_val, ...) \
$tuple_set_10(__VA_ARGS__), \
(_val)
#define $tuple_set_12(_val, ...) \
$tuple_set_11(__VA_ARGS__), \
(_val)
#define $tuple_set_13(_val, ...) \
$tuple_set_12(__VA_ARGS__), \
(_val)
#define $tuple_set_14(_val, ...) \
$tuple_set_13(__VA_ARGS__), \
(_val)
#define $tuple_set_15(_val, ...) \
$tuple_set_14(__VA_ARGS__), \
(_val)
#define $TUPLE_SET_FUN(_idx,...) \
$tuple_set_##_idx
#define $TUPLE_SET_FUN_IDX( \
_0,_1, \
_2,_3, \
_4,_5, \
_6,_7, \
_8,_9, \
_10,_11, \
_12,_13, \
_14, \
...) \
$TUPLE_SET_FUN(__VA_ARGS__)
#define $TUPLE_SET_ARG(_N,...) \
$TUPLE_SET_FUN_IDX(__VA_ARGS__, $TUPLE_ARG_LST_15)
#define $tuple_set(...) = { \
$TUPLE_SET_ARG($TUPLE_MAX_ARG,__VA_ARGS__, $TUPLE_ARG_LST_15)(__VA_ARGS__) \
}
#define $tuple(_var, ...) \
$TUPLE_ARG( \
$TUPLE_MAX_ARG,__VA_ARGS__, \
$TUPLE_ARG_LST_15 \
) \
( \
__VA_ARGS__, \
$_1,$_2,$_3,$_4,$_5,$_6,$_7,$_8,$_9,$_10,$_11,$_12,$_13,$_14,$_15 \
)\
__unused _var $tuple_set(__VA_ARGS__)
#endif
assign_code{
// $tuple(v_1, @"二狗");
// BLOG((v_1.$_1));
//
//
// $tuple(v_2, CGRectMake(0, 0, 100, 100));
// BLOG(v_2.$_1.size.height);
//
// $tuple(v_3, @"我是二狗", "他是癟三兒", @10);
struct{
struct{
struct{
struct{
typeof(1002202) $_4;
};
typeof("我愛吃狗肉") $_3;
};
typeof("C字符串") $_2;
};
typeof(@"二狗") $_1;
} __attribute__((__unused__)) v_4 = { (1002202), ("我愛吃狗肉"), ("C字符串"), (@"二狗") };
$tuple(v_4,@"二狗","C字符串", "我愛吃狗肉",1002202);
}
總結(jié)
- 以上就是本人掌握的
宏的使用技巧, 這些技巧需要花費(fèi)大量的精力去研究, 說(shuō)白了就是跳出傳統(tǒng)的思維, 這些使用技巧在當(dāng)今的網(wǎng)絡(luò)中基本沒人拿出來(lái)介紹, 包括在國(guó)外, 所以也是一筆寶貴的經(jīng)驗(yàn),當(dāng)然這些利用宏實(shí)現(xiàn)的所謂的泛型, 過(guò)程相當(dāng)復(fù)雜, 在C++中,實(shí)現(xiàn)出來(lái)有自己的泛型編譯支持, 同時(shí)更為復(fù)雜和強(qiáng)大,學(xué)無(wú)止境, 編程的路上只有往下學(xué)才能掌握本質(zhì)的東西