go语言学习--go中闭包
关于闭包有句话说的很好,闭包捕获的变量和常量是引用传递不是值传递。
Go语言支持匿名函数,即函数可以像普通变量一样被传递或使用。
使用方法如下:
package main import (
"fmt"
) func main() {
var v func(a int) int
v = func(a int) int {
return a * a
}
fmt.Println(v(6))
//两种写法
v1 := func(i int) int {
return i * i }
fmt.Println(v1(7))
}
GO语言的匿名函数就是闭包,以下是《GO语言编程》中对闭包的解释
基本概念
闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者
任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码块(由于自由变量包含
在代码块中,所以这些自由变量以及它们引用的对象没有被释放)为自由变量提供绑定的计算环
境(作用域)。
闭包的价值
闭包的价值在于可以作为函数对象或者匿名函数,对于类型系统而言,这意味着不仅要表示
数据还要表示代码。支持闭包的多数语言都将函数作为第一级对象,就是说这些函数可以存储到
变量中作为参数传递给其他函数,最重要的是能够被函数动态创建和返回。
一个函数和与其相关的引用环境,组合而成的实体:
package main
import "fmt"
func main() {
var f = Adder()
fmt.Println(f(1), "-")
fmt.Println(f(20), "-")
fmt.Println(f(300), "-")
}
func Adder() func(int) int {
var x int
return func(delta int) int {
x += delta
return x
}
}
使用闭包的注意点
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
闭包的注意点
由于闭包使的函数的变量保存在内中,会出现值被替换的情况
package main
import "fmt"
func main() {
var flist []func()
for i := 0; i < 3; i++ {
flist = append(flist, func() {
fmt.Println(i)
})
}
for _, f := range flist {
f()
}
}
我们可以看到结果全是3。为什么呢?我们可以打印下循环中i的地址
package main
import "fmt"
func main() {
var flist []func()
for i := 0; i < 3; i++ {
fmt.Println(&i)
flist = append(flist, func() {
fmt.Println(i)
})
}
for _, f := range flist {
f()
}
}
发现运行的结果
0xc0420080a8
0xc0420080a8
0xc0420080a8
3
3
3
i指向的地址是一样的,那么就很明了了i的变量被保存了,最后的循环把i的值变成了3
如何改进呢,我们只需要每次初始化一个i就可以了
package main
import "fmt"
func main() {
var flist []func()
for i := 0; i < 3; i++ {
i := i //给i变量重新赋值,
fmt.Println(i)
flist = append(flist, func() {
fmt.Println(i)
})
}
for _, f := range flist {
f()
}
}
go语言学习--go中闭包的更多相关文章
- go语言学习--go中godep的使用小结
go中的godep 本文参考:http://www.cnblogs.com/me115/p/5528463.html#h20 http://studygolang.com/articles/4385 ...
- go语言学习--map中键值得删除
测试 map1 中是否存在 key1: 在例子 8.1 中,我们已经见过可以使用 val1 = map1[key1] 的方法获取 key1 对应的值 val1.如果 map 中不存在 key1,val ...
- go语言学习--go中的map切片
//定义一个结构 type Car struct { Brand string Age int } func Pluck() map[int][]Car { carMap := make(map[in ...
- 大一C语言学习笔记(5)---函数篇-定义函数需要了解注意的地方;定义函数的易错点;详细说明函数的每个组合部分的功能及注意事项
博主学习C语言是通过B站上的<郝斌C语言自学教程>,对于C语言初学者来说,我认为郝斌真的是在全网C语言学习课程中讲的最全面,到位的一个,这个不是真不是博主我吹他哈,大家可以去B站去看看,C ...
- R语言学习笔记——C#中如何使用R语言setwd()函数
在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//")> setwd("e:\桌面\")> s ...
- 如何设计一门语言(七)——闭包、lambda和interface
人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...
- go语言学习笔记
Go语言学习基本类型Bool 取值范围:true,false (不可以用数字代替)Int/uint 根据平台可能为32或64位int8/uint8 长度:1字节 取值范围-128~127/0~255b ...
- Go语言学习笔记七: 函数
Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...
- 如何理解并学习javascript中的面向对象(OOP) [转]
如果你想让你的javascript代码变得更加优美,性能更加卓越.或者,你想像jQuery的作者一样,写出属于自己优秀的类库(哪怕是基于 jquery的插件).那么,你请务必要学习javascript ...
随机推荐
- hdu1846 Brave Game 博弈
十年前读大学的时候,中国每年都要从国外引进一些电影大片,其中有一部电影就叫<勇敢者的游戏>(英文名称:Zathura),一直到现在,我依然对于电影中的部分电脑特技印象深刻.今天,大家选择上 ...
- 线程---同步(synchronized)
实现线程同步的一种方式介绍: 思路: 首先,需要被协调的类,先实现线程,并重写run方法 然后,在被协调的类中私有化控制器,控制器实例化,由构造器带入. 其次,由控制器对象具体负责调用. 举例:循环输 ...
- AangularJS的表单验证
Angular能够将HTML5表单验证功能同它自己的验证指令结合起来使用 Angular提供了很多表单验证指令: 1. 必填项:验证表单输入是否填写,只需在html标签上标记required 如: ...
- Go Example--结构体
package main import "fmt" //定义一个私有结构体 type person struct { name string age int } func main ...
- 【mybatis源码学习】mybtias一级,二级缓存
转载:https://www.cnblogs.com/ysocean/p/7342498.html mybatis 为我们提供了一级缓存和二级缓存,可以通过下图来理解: ①.一级缓存是SqlSessi ...
- JS中map和foreach的区别以及some和every的用法
一.原生JS forEach()和map()遍历 共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前 ...
- Rendering on the Web
转自: https://developers.google.com/web/updates/2019/02/rendering-on-the-web Rendering on the Web Goog ...
- graalvm 简单试用
安装 地址 http://www.graalvm.org/downloads/ 配置环境变量 linux: export PATH=/path/to/graalvm/bin:$PATH mac: ...
- Linux 定时任务crontab使用
正好要搞一个定时删除数据的功能,想到linux 可设置定时器定时执行任务就学习了下~ 并不是所有的linux服务器上都装了crontab 像我这: [root@hehe local]# crontab ...
- zabbix--3.0--2
zabbix页面注意事项 1. 工作中使用zabbix常遇到的问题:生产一台机器告警了顺手关闭了,然后忘记打开了 2.监控项这里,也尽量不禁用,而是删除.能删除就删除 3.使用触发器的过程中,有时候 ...