

编程语言中的闭包
source link: https://hiberabyss.github.io/2018/03/06/programming-closure/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

闭包是现代的高级编程语言的一个重要概念, 本文会以 Golang 为例来介绍什么是闭包.
什么是闭包 (Closure)
在介绍闭包的定义之前, 我们先来看下闭包的示例代码:
package main
import "fmt"
func greeting(name string) func() string {
data := "Hello " + name
return func() string { return data }
}
func main() {
sayHi := greeting("hbliu")
fmt.Println(sayHi())
}
// result:
// Hello hbliu
这段代码就实现了闭包的效果: 虽然 greating
函数已经返回了, 但我们还可以访问到其内部的 data
局部变量. 下面是 CoolShell 对闭包的定义:
- 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
- 闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配
- 当在一个函数内定义另外一个函数就会产生闭包
在文章中给了另外一个定义: 闭包是指有权访问另一个函数作用域中的变量的函数
访问函数内局部变量一般都是通过返回使用了函数局部变量的内部函数来实现的. 由此可见, 为了支持闭包, 编程语言需要提供一下两个特性:
- 函数是 First Class Value, 即函数可以作为另一个函数的返回值或参数;
- 函数可以嵌套定义, 即可以在一个函数内部定义另外一个函数
闭包和对象都是既有函数也有数据, 可以用一句话来表明他们的区别: 对象是附有行为的数据,而闭包是附有数据的行为
闭包的优缺点
- 闭包可以减少全局变量的个数;
- 保存闭包外面的变量状态; 下面是一个示例:
下面的代买要用 goroutine 来打印一个 slice. 使用闭包前:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
arr := []int{2, 3}
for _, n := range arr {
go func() {
defer wg.Done()
fmt.Println(n)
}()
}
wg.Wait()
}
// resutl:
// 3
// 3
可以发现结果都是 3 , 这是因为 goroutine 用的都是同一个变量 n
.
我们可以使用闭包来避免这个问题:
// Package main provides ...
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(2)
arr := []int{2, 3}
for _, n := range arr {
func() {
backup := n
go func() {
defer wg.Done()
fmt.Println(backup)
}()
}()
}
wg.Wait()
}
// result:
// 3
// 2
闭包的缺点就是常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
References
Recommend
-
64
有问题,上知乎。知乎是中文互联网知名知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。
-
54
本文盘点2019年比较热的技术点,大家好根据前端发展趋势对自己的技术栈做一定规划,抓住重点。 本文主要聊以下几个技术点: Vue, React, Angular WebAssembly,PWA
-
71
程序员 - @HarveyLiu - 不谈论,简洁问题,也不管静态,动态问题,只谈论写起来是否舒服,有没有违和感。
-
36
[译] 编程语言中的 6 种内存模型(2016) Published at 2019-11-09 | Last Update 2019-11-09 本文翻译自一篇英文博客 The memory models th...
-
26
Java 是一门不断发展的语言,这是一件好事。然而,其他语言的一些特性也是值得研究的。语言的结构是人们思考问题的方式,也是人们设计解决方案的方式。学习或至少熟悉其他语言是借鉴其设计的好方法。 Java 是我学习的第一门语言并...
-
5
HBUACM为什么很多编程语言中数组都从0开始编号...
-
5
...
-
7
最近在参与KusionStack 内置的领域语言 ——KCL配置语言编译器 的开发,语言的语法中包括一个“索引签名”的概念,在参与社区讨论的时候发现很多小伙伴不明白这个“索引签名”是什么,于是自...
-
4
代码审计:如何在全新编程语言中发现漏洞? 作者:悠悠PM10 2022-09-20 12:53:15 具有安全意识的开发者仍然可能产生漏洞,因为很多开发用不到的特性、甚至编程语言官方非预期的情景不是开发者掌握的知识,代码安全...
-
9
各种编程语言中的 Lambda 我喜欢看 Conor Hoekstra 的视频,一方面是因为他是一位引人入胜的主持人,另一方面是因为他介绍了很多很多编程语言。我不懂那么多语言,所以能接触到不同语言如何解决相同的问题是件...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK