Fork me on GitHub

Go语言开发-过程式编程-自定义函数-闭包

5.6.3.闭包

闭包是指可以“捕获”同一作用域中所有常量和变量的一种函数,这意味着闭包在被调用时能够访问这些常量和变量,而不管闭包在何处被调用。这些常量或变量是否超出了作用域并不重要,只要闭包还在引用它们,它们就会一直存活着,以便闭包能够使用它们。

在Go语言中,所有的匿名函数(Go语言规范称之为函数常量)都是一个闭包。

闭包的创建语法与正常函数的几乎一样,但有一个关键区别:闭包没有名字(关键字func紧跟着左圆括号)。我们通常将闭包赋值给变量或将其放在结构体中(如map或切片)以使用它们。

我们已经介绍了一些使用闭包的例子,例如,当我们使用defer或go语句时,这些匿名函数就是闭包;americanise例子中的makeReplacerFunction()函数;第3章中strings.FieldsFunc()和strings.Map()函数接受的匿名函数参数;以及本章中的createCounter()和logPanics()函数。尽管如此,我们还是要再介绍几个小例子。

闭包的一个用途是提供一个封装函数并预先定义一些参数。例如,假如我们希望针对不同的文件名追加不同的后缀。实际上,我们希望能隐藏字符串的连接操作,这样就可以只需要一个参数(即,文件名),但另一个参数不需要变化(即,后缀)。

变量addPng和addJpg持有对匿名函数(即,闭包)的引用,这些引用可以像普通命名函数一样被调用。

在实际使用中,当我们希望创建多个类似的函数时,我们通常使用一个工厂函数,即一个返回函数的函数,而不是分别创建每个函数。下面是一个工厂函数,它返回一个向文件名追加后缀的函数,但前提是文件名的后缀不存在。

MakeAddSuffix()工厂函数返回一个闭包,该闭包在创建时指定后缀变量,返回的闭包接受一个字符串参数(即,文件名),并返回一个文件名结合后缀的字符串。

上面的代码片段创建了两个闭包addZip()和addTgz(),并对其进行了调用。


目录


作者:Johnson
原创文章,版权所有,转载请保留原文链接。

发表评论

电子邮件地址不会被公开。 必填项已用*标注