旋量群是那时许多程式结构设计词汇都全力支持的几项采用方便的优点,但对于许多人来说,旋量群这个东西的确有点儿艰涩,不太好认知,我真的主要就可能有以下几个原因:
英语名首一好 虽说,我真的无论是英语 “closure” 还是中文“旋量群”,英语名都不太好,当然主要就是英语英语名首一好,英语罢了按字面上原意译者罢了。那是不是更快的英语名?我真的能参照低阶表达式(Higher-order function)的用法,就叫有状况表达式(Stateful function)。
不介绍没有旋量群时的读法 旋量群出现的历史好似那时了,但主要就是许多表达式式词汇,像 c/c++ 此类晚期被广为采用的工业词汇,是不全力支持旋量群的,但旋量群采用的许多情景,c/c++ 里面也会碰到并且也能化解,罢了同时实现方法不同,跟用旋量群来同时实现较之更不方便罢了。介绍 c/c++ 里头类似于情景的读法,能协助认知为何要有旋量群,进而更快的认知旋量群。
上面他们就试著一下,先预测不全力支持旋量群的一些词汇的读法,然后再对照全力支持旋量群的词汇的读法,把旋量群的原委预测确切,进而全盘比如说旋量群。
c 反弹表达式
反弹表达式(callback)是 c 词汇里常见的一种程式结构设计表现手法,的的同时实现许多触发器机能或者结构设计库 API 时,着实不可或缺。他们来看一看 c 里头一般如何做的(假定同时实现一个该事件的触发器处置机能)。
没学过 c 词汇也关系,标识符很单纯,应该能大体看不懂。
首先表述反弹表达式的类别 callback_t, 即类似 ” void callback (int event) {…} ” 的形式,表述加进了表达式指针的表述
接下去表述该事件注册登记USB register_callback
然后采用这个USB注册登记该事件 EVENT_RECV (比如是TCP的数据接收该事件)的处置表达式为 recv
上面的同时实现有个问题,就是在反弹表达式里无法访问调用者的数据(比如当前状况等),这样在实际采用中,显然是不可行的。
接下去他们改造一下。
首先修改反弹表达式的类别 callback_t, 增加一个参数 user_data,类别为通用指针(能传任何数据)。
该事件注册登记接口 register_callback,也同样增加一个参数 user_data。
然后注册登记该事件反弹时,传入 user_data。
以上就是 c 词汇里采用反弹的正常做法,通过在反弹表达式和注册登记反弹USB都增加一个通用指针类别参数,把外部数据传给反弹,进而使反弹表达式内部能访问外部数据,这样做能正常工作,但有几个问题:
反弹表达式和注册登记反弹USB需要增加参数 user_data,且要显式的传递 user_data。
为了通用性, user_data 只能采用通用指针,采用不方便且编译器无法做类别检查。
c++ 表达式对象
注意:此处的表达式对象不是表达式,因为跟 Javascript、Python 等词汇的一切皆对象不一样,c++ 的表达式不是一等公民( first-class function ), 也就是表达式不是对象,不能有成员变量。
c++ 是兼容 c 的,所以以上 c 的做法在 c++ 上也能同时实现。但 c++ 增加了面向对象的全力支持,因此能有许多不一样的读法。
首先先看一下c++面向对象的常规用法
c++ 全力支持运算符重载,因此能有上面读法
通过重载对象的括号运算符 (),进而让对象能像表达式一样直接调用,这样的对象叫做表达式对象( functor )。表达式对象除了能像表达式一样直接调用外,还有一个最大的好处,就是表达式对象能有成员变量,因此能保存数据,如果用来替代c的反弹将会非常方便。
上面他们就来试著修改一下。
该事件注册登记USB register_callback,反弹 callback 的类别变为表达式对象
采用表达式对象来重新同时实现
能看到,通过采用表达式对象,能避免c反弹读法的问题,的确是个很大的提升。实际上表达式对象在 c++ 的标准库中被大量的采用,但是c++的这种读法也不是就是完美的。 – 首先需要表述表达式对象, – 然后每次注册登记反弹时,都需要生成表达式对象,
对于有些人来说,这些步骤还是挺麻烦的,要是能把这些都省了,那就真的完美了。
旋量群
旋量群的读法就是把 c++ 的表达式对象的表述和创建都省了,完全由编译器或解释器自动化了(当然,实际上编译器或解释器内部不一定用表达式对象来同时实现,比如 Javascript 表达式本身就是对象,只要把外部变量保存到成员变量就能了)。
他们看一下 Javascript 旋量群的读法。
内部表达式 recv 访问了外部变量 user_data,因此变成了一个旋量群,能认为解释器会把 recv 表达式从一个普通表达式变成一个类似于c++表达式对象,这个对象有一个成员变量user_data,但是这些都是解释器自动完成的,因此非常方便。
Javascript 生成旋量群还能采用上面方法。
makeClosure 返回了一个内部表达式,由于这个内部表达式访问了它的外部变量 user_data, 因此变成一个旋量群。
其他词汇如 Python 对旋量群的用法,基本和 Javascript 类似于。