2019独角兽企业重金招聘Python工程师标准>>>

前言


我们经常所编程语言的的进步速度是落后于硬件的发展速度的。

但是最近几年,闭包语法在各个语言中都有自己的体现形式,例如

  •  C语言中使用函数指针作为回调函数的入口;

  •  Java和C#语言中的Lambda语法表达式;

  •  Objective-C语言中的Blocks语法;

  •  C#语言中的Delegates语法;

  •  C++语言中的Functions对象;

历史


Peter J. Landin 在1964年将术语 闭包 定义为一种包含 环境成分 和 控制成分 的实体,用于在他的SECD 机器上对表达式求值。Joel Moses 认为是 Landin 发明了 闭包 这一术语,用来指代某些其开放绑定(自由变量)已经由其语法环境完成闭合(或者绑定)的 lambda 表达式,从而形成了 闭合的表达式,或称闭包。

使用方法


C++语言中的Functions对象:

C++11标准开始支持闭包,这是一种特殊的函数对象,由特殊的语言结构—— lambda表达式 自动构建。

C++闭包中保存了全部nonlocal变量的拷贝或引用。

如果是对外界环境中的对象的引用,且闭包执行时该外界环境的变量已经不存在(如在调用栈上已经unwinding),那么可导致undefined behavior,因为C++并不扩展这些被引用的外界环境的变量的生命期。

常见代码如下:

//
//  main.cpp
//  Interface
//
//  Created by lewis on 4/30/15.
//  Copyright (c) 2015 lewis. All rights reserved.
//#include <iostream>
#include <string>
#include <vector>using namespace std;//构造string向量
vector<string> GetNameList()
{static vector<string> names;names.push_back("刘辉");names.push_back("李静波");names.push_back("崔亚允");names.push_back("赵雅");names.push_back("管辉");names.push_back("白志刚");names.push_back("王斌");names.push_back("白雅静");names.push_back("张浩");return names;
}void foo(string myname) {vector<string> names = GetNameList();//通过遍历string向量,使用闭包完成判断条件vector<string>::iterator i = find_if(names.begin(), names.end(), [&](const string& s){//判断操作值与参数相等是否相等return s == myname;});//输出判断得到的结果cout  <<(string)(*i) << endl;
}int main(int argc, const char * argv[]) {foo("刘辉");return 0;
}

1、声明闭包变量

C++中闭包的声明语法,要使用 function 类型来声明变量,如下所示

std::function<float(float)> colsure;

其中,第一个 float 代表了闭包的返回值类型,第二个 float 代表了闭包的参数数据类型为浮点型

2、赋值闭包变量

C++中闭包的赋值语法,要使用 [=] 或 [&] 符号开头,如下所示

colsure = [=](float f) {f += 10.0f;      return f;
};

其中, [=] 代表了我们将要进行的闭包传值是单向赋值

[&] 在使用过程中,经常作为引用传值使用,如下所示

std:function<float(float&)> col;
col = [&](float& f){f += 10.0f;      return f;
};

3、使用闭包变量

使用 [=] 和 [&] 声明并且赋值后的闭包变量,在使用结束后的结果如下

//声明一个浮点型变量float floatValue = 1.0f;//声明计算结果浮点型变量float resultValue = 0.0f;//使用[=]类型的闭包变量resultValue = colsure(floatValue);//输入结果std::cout<<floatValue<<":"<<resultValue<<endl;//使用[&]类型的闭包变量resultValue = col(floatValue);
std::cout<<floatValue<<":"<<resultValue<<endl;

通过打印的结果,

1.0:10.0
10.0:10.0

[=] 和 [&] 分别代表了值传递和引用传递的两种方式。

Objective-C中的Blocks变量:

Blocks语法支持的系统版本为OS X 8或者更高版本,iOS 4或者更高版本.

常见的代码如下:

//
//  main.m
//  BlockSample
//
//  Created by lewis on 4/30/15.
//  Copyright (c) 2015 lewis. All rights reserved.
//#import <Foundation/Foundation.h>NSArray *GetNameList()
{static NSMutableArray *names = nil;if (names == nil) {names = [[NSMutableArray alloc] init];[names addObject:@"刘辉"];[names addObject:@"崔亚允"];[names addObject:@"李静波"];[names addObject:@"赵雅"];[names addObject:@"管辉"];[names addObject:@"王斌"];[names addObject:@"张浩"];}return names;
}void foo(NSString *myname)
{//获取到姓名列表NSArray *names = GetNameList();//通过遍历数组对象,使用Block进行判断NSInteger index = [names indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {return [obj isEqualToString:myname];}];//输出结果NSLog(@"%@",names[index]);
}int main(int argc, const char * argv[])
{foo(@"崔亚允");return 0;
}

1、声明Block语法变量

float(^block)(float);

我们会发现,Blocks语法变量的声明语法与函数指针变量的声明语法 float(*pointer)(float); 非常类似,只是在运算符号上有区别;

2、赋值Block语法变量

block = ^ (float f){f += 10.0f;        return f;
};

在对Blocks变量进行赋值时,要注意所有的Block变量都是用 "^" 运算符号来开头,并且有返回值类型的Block变量,在Block代码块内部的return 返回类型要相同。

C#语言中的Lambda表达式:

Lambda表达式实在C#4中出现的语法糖,用来提高程序的开发效率,简化Func类型变量和delegate对象的写法。

常见的代码如下:

using System;
using System.Collections.Generic;namespace LambdaSample
{class MainClass{public static List<string> GetNameList(){List<string> names = new List<string> ();names.Add ("刘辉");names.Add ("崔亚允");names.Add ("李静波");names.Add ("赵雅");names.Add ("管辉");names.Add ("白志刚");return names;}public static void foo(string myname){//获取姓名列表List<string> names = GetNameList ();//通过Lambda表达式作为判断条件进行查询string result = names.Find ((x) => {return x == myname;});//输入查询结果Console.WriteLine(result);}public static void Main (string[] args){//测试foo ("崔亚允");}}
}

1、声明C#语言中的Lambda表达式变量

在C#语言中,可以通过 Func 类型来声明Lambda变量,如下所示:

Func<float,float> func;

或者使用 delegate 类型来声明Lambda变量,如下所示:

//定义一个delegate类型Interfacedelegate float Interface(float x);public static void Main (string[] args)
{     //使用Interface类型来声明Lambda变量     Inteface inter_func;
}

2、赋值C#语言中的Lambda表达式变量

在C#语言中,使用 => goes to 运算符来生成变量,如下所示:

func = (x) => {x += 10.0f;    return x;
};

=> goes to运算符的左边是闭包类型的浮点型参数,右边是闭包变量准备进行的逻辑运算,以 {} 包括。

3、使用C#语言中的Lambda表达式变量

和调用函数一样,如下所示:

//声明Func类型变量Func<float,float> func;//为func赋值Lambda闭包func = (x) => {x += 10.0f;    return x;
};float floatValue = 1.0f;float resultValue = 0.0f;//调用func变量,计算结果并且赋值给resultValueresultValue = func (floatValue);//进行输出Console.WriteLine (resultValue);

总结


其实在计算机科学中,闭包Closure)是词法闭包Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,有另一种说法认为闭包是由函数和与其相关的引用环境组合而成的实体。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。

需要注意的一点是

闭包一词经常和匿名函数混淆。这可能是因为两者经常同时使用,但是它们是不同的概念!!!!

转载于:https://my.oschina.net/u/2438875/blog/502369

[iOS、Unity、Android] 浅谈闭包的使用方法相关推荐

  1. Android 浅谈 Activity (下)

    Android 浅谈 Activity(中) 上节讲了数据传递和数据回传,这节讲一讲状态保存以及启动模式. 在使用Bundle传递数据时,要注意,Bundle的大小是有限制的 < 0.5MB,如 ...

  2. java中virtual关键字_浅谈virtual、abstract方法和静态方法、静态变量理解

    说点对这几个容易混淆的词的理解: 1.c++中的virtual方法的 virtual关键字主要是防止继承中重复继承父类的同一个方法而设置的标识. 2.virtual与abstract关键字的不同之处在 ...

  3. iOS 3D Touch浅谈

    一.什么是3D Touch? 3D Touch是iPhone 6s推出的一种可以让你与手机进行互动的全新方式.除了轻点.轻扫.双指开合这些熟悉的 Multi‑Touch 手势之外,3D Touch 还 ...

  4. 计算机节约ip,浅谈节约IP地址方法.doc

    浅谈节约IP地址的方法 刘荣欢 (理学院 信计0701 lrhbsym@126.com) 摘 要:随着Internet技术的发展及现代用户计算机的增多,原先以Ipv4标准的IP地址分配以存在严重的空间 ...

  5. 浅谈JVM(六):方法调用过程

    上一篇: 浅谈JVM(一):Class文件解析 浅谈JVM(二):类加载机制 浅谈JVM(三):类加载器和双亲委派 浅谈JVM(四):运行时数据区 浅谈JVM(五):虚拟机栈帧结构 6.方法调用过程 ...

  6. 【JavaScript闭包】JavaScript何为闭包,浅谈闭包的形成和意义

    谈到js,必然逃不了闭包. 闭包到底是啥呢?我查了不少资料,解释真的是各种各样,千奇百怪,令人困惑. 我们先来看看一下各种解释 红宝石书:闭包指的是那些引用了另一个函数作用域中变量的函数. mdn : ...

  7. 浅谈“闭包”,什么才是“闭包”思想!—— javascript

    先看一个简单小案例: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML&g ...

  8. Android 浅谈动画

    本文来自:安卓航班网 Android的animation由四种类型组成,在XML中分别通过以下四种Tag设置:         alpha     渐变透明度动画效果         scale    ...

  9. iOS 屏幕适配浅谈

    作者 | 钱凯 杏仁移动开发工程师,前嵌入式工程师,关注大前端技术新潮流. 前端开发的屏幕适配其实算是基本功,每个码农在长期实践中都有自己的总结. 在 iOS 平台上,苹果爸爸对适配的支持个人感觉很不 ...

最新文章

  1. 用 C 语言开发一门编程语言 — 字符串与文件加载
  2. 学会python编程容易吗-老男孩学Python编程后薪资待遇高吗?
  3. elasticsearch之查询扩展
  4. 计算机相关专业学习经验总结
  5. 【教程】写CSDN博客时 调整图片大小,图片居中
  6. 本地存储localStorage
  7. Exceptionless - .Net Core开源日志框架
  8. c语言在函数中传递指针,[求助]关于文件指针在函数中传递的问题
  9. java中static代码块_static怎样在java中修改代码块?
  10. mysql 子表 关联查询语句_MySQL-基本查询语句及方法,连表和子查询
  11. WinForm与WPF下跨线程调用控件
  12. 以前积攒的一个用Java程序生成验证码的代码
  13. 一个完整的机器学习模型的流程
  14. 微信支付跨平台软件架构
  15. 漳州帷博计算机科技,福建省漳州市芗城中学高二6月月考语文试题 含答案(11页)-原创力文档...
  16. “领域知识图谱的构建与应用”讲座学习笔记
  17. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一
  18. 【网络通信】Teardrop编程创造虚假IP包
  19. 和菜头_《写给应届毕业生的99条箴言》读书笔记
  20. 矩阵压缩降维动态规划递推【P1719 最大加权矩形】

热门文章

  1. hdu1541,坑爹的经典树状数组
  2. flutter 内网安装包生成二维码
  3. Java代码实现点赞功能
  4. java毕业设计—— 基于java+JSP+SSH的任务调度系统设计与实现(毕业论文+程序源码)——任务调度系统
  5. 微信加拿大服务器,微信新功能,在加拿大也可以任意刷人民币了
  6. windows10 20H2版本微软账户登录不上解决方法
  7. vs2017\vs2019 VGG19处理cifar-10数据集的TensorFlow实现
  8. 南开大学计算机宁博,周亚训 教授
  9. 获取处于选中状态的checkbox的id值
  10. Vue.js如何获得兄弟元素,子元素,父元素(DOM操作)