在The Swift programming langauge看到closures,但是不太理解是什么,有什么样的特性,能做什么Objective-C做不到的?编程初学者,求指教
语法上东西我就不说了。
计算机程序可以粗略的分成,代码+数据。初学者很容易就会将这两者对立起来,会认为代码就是代码,数据就是数据,两者是完全不同的。但实际上,两者可以统一起来的。将代码跟数据统一起来,是学习计算机编程的一道门槛。
可以参考,我以前的回答。回调函数是什么?
将数据保存起来,以后再使用,会觉得很自然。但将代码保持起来,以后再使用,很多人会觉得很别扭,难以理解。都是因为还没有过那道槛。
代码指令执行时候,会处于一定的环境,单纯将代码保存下来,还是不够的,需要将代码所处的环境也保存下来。闭包其实是,将代码跟代码所处于的环境做为一个整体来看待。周围的环境,表现为代码所使用的数据。在有些语言中,这个概念叫代码块(block),匿名函数(lambda)等等。
数据跟代码不再人为割裂开来,统一起来看待。闭包就会是很自然的概念。数据可以传递,从一个地方传递到另一个地方,并且以后再使用。闭包从某个角度来说,也是数据,当然也可以传递,从一个函数传递到另一个函数,也可以保持下来,以后再调用。因为将环境也保持下来了,以后调用的时候,就还原当时的情况,延迟执行,就很容易,很自然地实现了。而延迟执行有什么作用?就是另一个话题了。
<code class="language-text">function makeCounter() local count = 0 return function() count = count + 1 return count end </code>
<code class="language-js"><span class="kd">function</span> <span class="nx">funA</span><span class="p">(</span><span class="nx">callback</span><span class="p">){</span> <span class="nx">alert</span><span class="p">(</span><span class="nx">callback</span><span class="p">());</span> <span class="p">}</span> <span class="kd">function</span> <span class="nx">funB</span><span class="p">(){</span> <span class="kd">var</span> <span class="nx">str</span> <span class="o">=</span> <span class="s2">"Hello World"</span><span class="p">;</span> <span class="c1">// 函数funB的局部变量,函数funA的非局部变量</span> <span class="nx">funA</span><span class="err">(</span> <span class="kd">function</span><span class="err">()</span><span class="p">{</span> <span class="k">return</span> <span class="nx">str</span><span class="p">;</span> <span class="p">}</span> <span class="err">);</span> <span class="p">}</span> </code>
<code class="language-common-lisp"><span class="p">(</span><span class="nb">defun</span> <span class="nv">stackpush</span> <span class="p">(</span><span class="nv">stack</span> <span class="nv">x</span><span class="p">)</span> <span class="p">(</span><span class="nb">cons</span> <span class="nf">#'</span><span class="p">(</span><span class="k">lambda</span> <span class="p">()</span> <span class="nv">x</span><span class="p">)</span> <span class="nf">#'</span><span class="p">(</span><span class="k">lambda</span> <span class="p">()</span> <span class="nv">stack</span><span class="p">)))</span> <span class="p">(</span><span class="nb">defun</span> <span class="nv">stackpop</span> <span class="p">(</span><span class="nv">stack</span><span class="err">)</span> <span class="p">(</span><span class="nb">apply</span> <span class="p">(</span><span class="nb">cdr</span> <span class="nv">stack</span><span class="p">)</span><span class="no">nil</span><span class="p">))</span> <span class="p">(</span><span class="nb">defun</span> <span class="nv">stacktop</span> <span class="p">(</span><span class="nv">stack</span><span class="p">)</span> <span class="p">(</span><span class="nb">apply</span> <span class="p">(</span><span class="nb">car</span> <span class="nv">stack</span><span class="p">)</span> <span class="no">nil</span><span class="p">))</span> </code>