我讨厌我爱你:了解关闭和完成

封闭是Swift的一个很棒的小功能,我绝对讨厌。 它们提供了许多好处,当我第一次以正式形式遇到它们时,就被它们让一个类遍历另一个函数的范围来获取和设置我从未见过的变量的能力所震惊。

理论上闭包是如何工作的:

在我自己实施它们之后,我很快意识到它们确实是可怕的生物,使我的生活更加艰难。

闭包在实践中如何工作:

但是,很多……我的意思是大量的练习,阅读和询问一百万个问题,我很快就开始理解它们的工作方式以及何时以及如何使用它们。 之后,我觉得也许是我最初想到它们的方式引起了我的困惑,所以我想用做晚饭的比喻来简单地详细解释它们。

一个简单的关闭函数说明:

现在,当我们调用函数时,就是魔术发生了!

我们从函数makeDinner()上的紫色箭头开始。 当我们调用此函数时,我们需要为其提供两个参数,第一个是一个字符串(我们选择“牛排”),第二个是一个函数。 我们赋予原始功能(makeDinner)的功能是choiceSides。

当我们的makeDinner()实现在调用完成函数时达到其代码中的要点时,我们实际上停止了执行并开始运行传入的函数。 有一些方法可以运行makeDinner()的其余部分,而无需等待第二个完成,但是我没有在此处实现它以保持简单(好像)。

ChooseSides()函数的实质无所谓,只是知道它以字符串作为自己的参数,这是由makeDinner()提供的,当我们在类实例anthony上首次调用它时,我们直接将其提供给makeDinner()。

choiceSides()的结果是一个字符串,该字符串冒泡返回并进入makeDinner,并替换makeDinner()首次调用chooseSides()的位置(在我们打印的字符串的第二个插值处)。

如果这一切看起来都是令人费解的,我常常想知道我这样做时是否没有违反自然法则,但是直到现在仍然有效。

再往前走,我们可以直接从choiceSides()中提取代码,然后将其直接用作makeDinner()作为封闭函数,而不用传入choiceSides()作为参数。 查看上面代码的下半部分,看看原始方法和闭包函数方法都可以打印出相同的内容!