关于闭包有句话说的很好,闭包捕获的变量和常量是引用传递不是值传递。

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中闭包的更多相关文章

  1. go语言学习--go中godep的使用小结

    go中的godep 本文参考:http://www.cnblogs.com/me115/p/5528463.html#h20 http://studygolang.com/articles/4385 ...

  2. go语言学习--map中键值得删除

    测试 map1 中是否存在 key1: 在例子 8.1 中,我们已经见过可以使用 val1 = map1[key1] 的方法获取 key1 对应的值 val1.如果 map 中不存在 key1,val ...

  3. go语言学习--go中的map切片

    //定义一个结构 type Car struct { Brand string Age int } func Pluck() map[int][]Car { carMap := make(map[in ...

  4. 大一C语言学习笔记(5)---函数篇-定义函数需要了解注意的地方;定义函数的易错点;详细说明函数的每个组合部分的功能及注意事项

    博主学习C语言是通过B站上的<郝斌C语言自学教程>,对于C语言初学者来说,我认为郝斌真的是在全网C语言学习课程中讲的最全面,到位的一个,这个不是真不是博主我吹他哈,大家可以去B站去看看,C ...

  5. R语言学习笔记——C#中如何使用R语言setwd()函数

    在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//")> setwd("e:\桌面\")> s ...

  6. 如何设计一门语言(七)——闭包、lambda和interface

    人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...

  7. go语言学习笔记

    Go语言学习基本类型Bool 取值范围:true,false (不可以用数字代替)Int/uint 根据平台可能为32或64位int8/uint8 长度:1字节 取值范围-128~127/0~255b ...

  8. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  9. 如何理解并学习javascript中的面向对象(OOP) [转]

    如果你想让你的javascript代码变得更加优美,性能更加卓越.或者,你想像jQuery的作者一样,写出属于自己优秀的类库(哪怕是基于 jquery的插件).那么,你请务必要学习javascript ...

随机推荐

  1. 有关O_APPEND标志和lseek()的使用

    编程之路刚刚开始,错误难免,希望大家能够指出. O_APPEND表示以每次写操作都写入文件的末尾.lseek()可以调整文件读写位置. <<Linux/UNIX系统编程手册>> ...

  2. 【BZOJ3242】【UOJ#126】【NOI2013】快餐店

    NOI都是这种难度的题怎么玩嘛QAQ 原题: 小T打算在城市C开设一家外送快餐店.送餐到某一个地点的时间与外卖店到该地点之间最短路径长度是成正比的,小T希望快餐店的地址选在离最远的顾客距离最近的地方. ...

  3. 【mysql】创建索引

    一.联合唯一索引 项目中需要用到联合唯一索引: 例如:有以下需求:每个人每一天只有可能产生一条记录:处了程序约定之外,数据库本身也可以设定: 例如:t_aa 表中有aa,bb两个字段,如果不希望有2条 ...

  4. struts2(三)拦截器

    拦截器 需求 如果要访问某一个action类中的某一个方法的内容,如果是admin用户,则访问,如果不是admin用户,则不能访问. 实现 缺点  权限判断的代码和业务逻辑代码混合在一起了 利用拦截器 ...

  5. 这样学习C语言最有效(高级技巧)——共勉

    第一章 学习C语言的起跑线 1.1 C语言已死? 本资料描述的是使用C语言的高级技巧,力求将你的C语言能力由"基础"提升为"高级".但是学习态度胜过学习方法,在 ...

  6. Djangon 基础总结 汇总 从请求到返回页面的过程,

    第一步我是用户 现在 浏览器上输入地址 ---> 发送给服务   来请求返回当前的页面 第二步  服务端获得我当前的客户端要求访问的地址   第三步 服务端去urls.py中去,来看是要访问那个 ...

  7. Python高阶函数_map/reduce/filter函数

    本篇将开始介绍python高阶函数map/reduce/filter的用法,更多内容请参考:Python学习指南 map/reduce Python内建了map()和reduce()函数. 如果你读过 ...

  8. resolve和reject不会终结Promise的参数函数的执行

  9. 在CentOS 6上使用 AWStats 分析 httpd 和 Tomcat 日志

    准备工作: Awstats 是由perl语言编写的,所以要首先准备好awstats的运行环境.# yum install –y perl*   Apache 一.首先,要安装apache服务器,并且启 ...

  10. Python正则表达式学习记录

    常用的命令: http://www.runoob.com/python/python-reg-expressions.html 使用中相关注意问题: 1. 中括号里的表示从N到M需要用横线‘-’, 而 ...