二者的定義:
Block :
^ return type (parameter list) {function body}
其中,返回類型的參數(shù)表時(shí)可以省略的,即最簡(jiǎn)略的方式:
^ {function body}
Lambda :
[capture list] (parameter list) -> return type {function body}
其中,返回類型和參數(shù)表也是可以省略的:
[capture list] {function body}
捕獲(截獲)變量
二者的定義出了使用的運(yùn)算符不同之外, Lambda 還比 Block 多了一個(gè) "capture list",即捕獲列表,其實(shí) Block 中也有對(duì)變量的捕獲:
Block 中的捕獲:如果要想在 Block 中截獲一個(gè)變量,可以直接使用這個(gè)變量,但是此時(shí)使用的僅是這個(gè)變量的拷貝值,如果要在 Block 中修改這個(gè)變量,需要在變量之前使用
__block
來修飾。
Lambda 中的捕獲:Lambda 捕獲變量只針對(duì)于局部非 static 變量,如果要使用 static 變量或者使用定義在當(dāng)前作用域的父級(jí)作用域的變量時(shí),可以直接使用。要在 Lambda 中捕獲的變量需在捕獲列表里聲明。并且,捕獲分為“值捕獲”和“引用捕獲”,如果變量名為 value,
那么值捕獲為:
[value]{}
引用捕獲為:
[&value]{}
隱式捕獲可以讓編譯器自動(dòng)推斷 Lambda 中要捕獲的變量,隱式的值捕獲:
[=]{}
隱式的引用捕獲:
[&]{}
返回值
Block 的返回類型是可以省略的,而在 《C++ Primer》 中,關(guān)于 Lambda 的返回類型是這樣說的:如果 Lambda 中含有除了 return 語(yǔ)句之外的其它語(yǔ)句,那么返回類型不可省略,但是實(shí)際測(cè)試下也是可以省略的,這個(gè)應(yīng)該和編譯器有關(guān)。
其它
Block “這是個(gè)位于 C 層面的特性,因此,只要有支持此特性的編譯器,以及能執(zhí)行塊的運(yùn)行期組件,就可以在 C、C++、Objective-C 、Objective-C++ 代碼中使用它”(Effective Objective-C 2.0 第 149 頁(yè))
實(shí)際測(cè)試確實(shí)是這樣,以下是一個(gè)簡(jiǎn)單的 CPP 程序:
int main(int argc, const char * argv[]) {
auto testLambda = [](int a , int b){
if (a > b){
return a;
}
else {
return b;
}
};
auto testBlock = ^(int a, int b){
return (a > b) ? a : b;
};
std::cout << testLambda(5, 9) << std::endl;
std::cout << testBlock(5, 9) << std::endl;
return 0;
}
我們?cè)?CPP 中同時(shí)使用了 Lambda 和 Block ,二者都打印了 9 。同時(shí),還看到 Lambda 中含有除了 return 之外的其它語(yǔ)句而沒有聲明返回類型。