Golang闭包
2015-10-15 15:49
483 查看
1 形式含义
所谓闭包就是一个函数“捕获”了和它在同一作用于的其他常量和变量。
从形式上看,在Golang中,所有的匿名函数都是闭包。闭包的创建方式和普通函数几乎一致,只有一个关键区别:闭包没有名字。
我们来看两个例子
2 实质含义
仅仅从形式上将闭包简单理解为匿名函数是不够的,还需要理解闭包实质上的含义。
实质上看,闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。由闭包的实质含义,我们可以推论:闭包获取捕获变量相当于引用传递,而非值传递;对于闭包函数捕获的常量和变量,无论闭包何时何处被调用,闭包都可以使用这些常量和变量,而不用关心它们表面上的作用域。
我们用一个例子来进行验证。
首先强调一点,x是闭包中被捕获的变量,y只是闭包内部的局部变量,而非被捕获的变量。因此,对于每一次引用,x的地址都是固定的,是同一个引用变量;y的地址则是变化的。另外,闭包被引用了两次,由此产生了两个闭包实例,即addNum := addNumber(5)和addNum1 :=addNumber(5)是两个不同实例,其中引用的两个x变量也来自两个不同的实例。
本文出自 “说话的白菜” 博客,谢绝转载!
所谓闭包就是一个函数“捕获”了和它在同一作用于的其他常量和变量。
从形式上看,在Golang中,所有的匿名函数都是闭包。闭包的创建方式和普通函数几乎一致,只有一个关键区别:闭包没有名字。
我们来看两个例子
addPng := func(name string) string { return name + ".png" } addJpg := func(name string) string { return name + ".jpg" } filename := "abc" fmt.Println(addPng(filename), addJpg(filename))结果如下
// 工厂函数,返回值也是一个函数 funcaddSuffix(suffix string) func(string) string { return func(name string) string { if !strings.HasSuffix(name, suffix) { name = name + suffix } return name } } … func main() { … addZip := addSuffix(".zip") addTgz := addSuffix(".tar.gz") fmt.Println(addZip(filename),addTgz(filename)) }
2 实质含义
仅仅从形式上将闭包简单理解为匿名函数是不够的,还需要理解闭包实质上的含义。
实质上看,闭包是由函数及其相关引用环境组合而成的实体(即:闭包=函数+引用环境)。闭包在运行时可以有多个实例,不同的引用环境和相同的函数组合可以产生不同的实例。由闭包的实质含义,我们可以推论:闭包获取捕获变量相当于引用传递,而非值传递;对于闭包函数捕获的常量和变量,无论闭包何时何处被调用,闭包都可以使用这些常量和变量,而不用关心它们表面上的作用域。
我们用一个例子来进行验证。
funcaddNumber(x int) func(int) { fmt.Printf("x: %d, addr of x:%p\n", x, &x) return func(y int) { k := x + y x = k y = k fmt.Printf("x: %d, addr of x:%p\n", x, &x) fmt.Printf("y: %d, addr of y:%p\n", y, &y) } } func main() { addNum := addNumber(5) addNum(1) addNum(1) addNum(1) fmt.Println("---------------------") addNum1 := addNumber(5) addNum1(1) addNum1(1) addNum1(1) }运行结果
首先强调一点,x是闭包中被捕获的变量,y只是闭包内部的局部变量,而非被捕获的变量。因此,对于每一次引用,x的地址都是固定的,是同一个引用变量;y的地址则是变化的。另外,闭包被引用了两次,由此产生了两个闭包实例,即addNum := addNumber(5)和addNum1 :=addNumber(5)是两个不同实例,其中引用的两个x变量也来自两个不同的实例。
本文出自 “说话的白菜” 博客,谢绝转载!
相关文章推荐
- google host
- Google 的GSON使用详解
- GoogleCardsActivity 效果很好
- 我理解的django的CSRF防御!
- mongo复制,备份,恢复
- golang reflect
- 修改Exchange2010 OWA主界面企业logo
- godeps 坑
- 在IntelliJ IDEA14中安装go语言插件
- 1go网消费联盟
- somedargon@0.0.0.0's password:
- VIEWGOOD(远古)供应校园网视频点播系统
- SHA1算法原理
- django 静态资源配置详解
- [Django模板系统]方法调用与无效变量处理
- go学习笔记
- [Django模板系统]用点号进行深度变量的查找
- objc category的秘密
- objc category的秘密
- Why "INSERT ... ON CONFLICT DO NOTHING/UPDATE" Good for performance