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 ...
随机推荐
- Two Sum II - Input array is sorted
Given an array of integers that is already sorted in ascending order, find two numbers such that the ...
- linux服务器的日志管理
消息紧急程度排行 emerg:该系统不可用 alert:需要立即修改 crit:紧急情况 err:错误信息 warning:预警信息 notice:具有重要性的普通条件 info:提供信息的消息 de ...
- bash常识
文章目录 比较是否相等 = 字符串操作 字符串变量的截取操作 字符串替换 字符串比较 取长度 查找子串的位置 选取子串 fork, exec, source fork exec source 补充 其 ...
- day 56 jQuery学习
1.补充:each 描述:一个通用的迭代函数,它可以用来无缝迭代对象和数组.数组和类似数组的对象通过一个长度属性(如一个函数的参数对象)来迭代数字索引,从0到length - 1.其他对象通过其属性名 ...
- JavaScript编码风格
最近在看前端大牛Nicbolas C.Zakas的<编写可维护的JavaScript代码>一书.觉得里面的很多知识点都写的很好,所以,就写篇博文,总结一下吧!编码规范对于程序设计来说是很重 ...
- js将foo-bar转为fooBar
这是一道js的面试题,就是考察将普通面命转为小驼峰命名 <!DOCTYPE html> <html lang="en"> <head> < ...
- HanLP二元核心词典详细解析
本文分析:HanLP版本1.5.3中二元核心词典的存储与查找.当词典文件没有被缓存时,会从文本文件CoreNatureDictionary.ngram.txt中解析出来存储到TreeMap中,然后构造 ...
- 《Windows核心编程》第3章——深入理解handle
本文借助windbg来理解程序中的函数如何使用handle对句柄表进行查询的.所以先要开启Win7下Windbg的内和调试功能. 解决win7下内核调试的问题 win7下debug默认无法进行内核调试 ...
- SQL 更新修改删除一个表,库存自动增减的写法
create trigger tri_asbon asb for insert as begin declare @rk int declare @ck int declare @sid varcha ...
- JDK官网下载教程
进入官网网址 https://www.oracle.com/index.html 登录成功后,即可进行下载! PS:新版谷歌浏览器可能会出现无法下载的问题,使用IE浏览器即可.