美文网首页
OC 的 Block 和 C++ 的 Lambda

OC 的 Block 和 C++ 的 Lambda

作者: 贾佳菊 | 来源:发表于2015-08-10 23:33 被阅读801次

    二者的定义:

    Block :

    ^ return type (parameter list) {function body}
    

    其中,返回类型的参数表时可以省略的,即最简略的方式:

    ^ {function body}
    

    Lambda :

    [capture list] (parameter list) -> return type {function body}
    

    其中,返回类型和参数表也是可以省略的:

    [capture list] {function body}
    

    捕获(截获)变量

    二者的定义出了使用的运算符不同之外, Lambda 还比 Block 多了一个 "capture list",即捕获列表,其实 Block 中也有对变量的捕获:

    Block 中的捕获:如果要想在 Block 中截获一个变量,可以直接使用这个变量,但是此时使用的仅是这个变量的拷贝值,如果要在 Block 中修改这个变量,需要在变量之前使用

    __block
    

    来修饰。

    Lambda 中的捕获:Lambda 捕获变量只针对于局部非 static 变量,如果要使用 static 变量或者使用定义在当前作用域的父级作用域的变量时,可以直接使用。要在 Lambda 中捕获的变量需在捕获列表里声明。并且,捕获分为“值捕获”和“引用捕获”,如果变量名为 value,
    那么值捕获为:

    [value]{}
    

    引用捕获为:

    [&value]{}
    

    隐式捕获可以让编译器自动推断 Lambda 中要捕获的变量,隐式的值捕获:

    [=]{}
    

    隐式的引用捕获:

    [&]{}
    

    返回值

    Block 的返回类型是可以省略的,而在 《C++ Primer》 中,关于 Lambda 的返回类型是这样说的:如果 Lambda 中含有除了 return 语句之外的其它语句,那么返回类型不可省略,但是实际测试下也是可以省略的,这个应该和编译器有关。

    其它

    Block “这是个位于 C 层面的特性,因此,只要有支持此特性的编译器,以及能执行块的运行期组件,就可以在 C、C++、Objective-C 、Objective-C++ 代码中使用它”(Effective Objective-C 2.0 第 149 页)
    实际测试确实是这样,以下是一个简单的 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;
    

    }

    我们在 CPP 中同时使用了 Lambda 和 Block ,二者都打印了 9 。同时,还看到 Lambda 中含有除了 return 之外的其它语句而没有声明返回类型。

    相关文章

      网友评论

          本文标题:OC 的 Block 和 C++ 的 Lambda

          本文链接:https://www.haomeiwen.com/subject/aesiqttx.html