闭包基础概念理解

谈谈闭包

本文讨论闭包的相关概念,大部分代码使用Swift编写。Swift对闭包有着良好的支持。这是因为,Swift被设计成一门一定程度上支持函数式编程范式的编程语言。而函数式编程和闭包有着紧密的联系。本文着重讨论的也是函数式编程和闭包之间的关系。

变量,约束,环境和函数

在讨论闭包之前,需要先明晰一些简单的概念。

变量

计算机程序语言中必不可少的一部分是它需要提供一种通过名字去使用计算对象的方式。也就是,我们需要能为计算对象标识一个名字。名字标识符就是我们常说的变量,而它的值就是它所对应的那个对象。如果要在编程语言中使用这些变量,我们就需要有将值和变量名关联起来,和在需要时又可以将值提取出来的能力。这就意味着编程语言需要提供某种存储能力,将变量名和值的对应关系存储下来,以便需要时使用。

约束

将变量名关联于对应的值,就构成了一个约束。任何变量至多只能有一个约束。这很容易理解,因为使用变量名取数据时,你当然希望它指明的是明确而且唯一的值。这也是为何把变量名和值的对应关系称为约束的原因。

环境

一系列这种名字和值对应关系(约束)的存储,就可以称之为环境。环境对于程序语句是至关重要的,因为它确定了每个表达式的上下文。甚至,我们可以说环境决定了表达式的含义。因为,即便是确定像(1 + 1)这么简单的语句的具体含义,也有赖于环境来确定+是表达加法的运算符号。我们可以假定程序的运行时拥有一个全局环境,这个环境里包含了所有关联于基本过程的符号的值。例如,符号+就在全局环境中被约束到基本的加法运算。

函数

函数,是大部分编程语言都存在的概念。它在不同语言中这个概念也存在着细微的区别。在面向对象编程语言中称之为“方法”,在函数式编程语言中称之为“过程”。无论被称为什么名字,它们都拥有的共同基本含义是:它是编程语言的一种基本的抽象手段,使我们可以将一组操作作为一个单元组合起来,并为这组操作命名。这样我们就可以通过一个简单的名字操作一组复杂的操作。而对于不同的编程语言中“函数”这一实体所存在的细微差别,我们会在后文中通过对“闭包”的探讨加以说明。

闭包

在说闭包之前,需要先清楚“自由变量”的概念。在某个作用域中,如果使用未在本作用域中声明的变量,对于此作用域来说,该变量就是一个自由变量。

闭包,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。另一种说法认为闭包并不是函数,而是由函数和与其相关的引用环境组合而成的实体。这是因为,闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。而函数只会有一个实例。这两种定义对闭包的看法并没有不同,只是对函数的定义不同。前者对函数的定义更宽松,后者则更为严格。

原文

posted @ 2017-06-16 09:55  上水的花  阅读(271)  评论(0编辑  收藏  举报