一、匿名函数

  定义:没有函数名的函数。

  作用:在go语言中目前了解的作用就是用于构成闭包。

  *注:由于javascript不存在块级作用域,故匿名函数常用来包含代码以不污染全局命名空间,运行后销毁环境。

    ----来自知乎回答:http://www.zhihu.com/question/34649602

  使用方法及其原理请参考:http://www.cnblogs.com/chenxianbin89/archive/2010/01/28/1658392.html

  使用举例

  (1)

  1. a := func() {
  2. fmt.Println(1)
  3. }
  4. a() //输出:1

  (2)带参数

  1. b := func(arg int) {
  2. fmt.Println(arg)
  3. }
  4. b(2) //输出:2
  5.  
  6. (func(arg int) {
  7. fmt.Println(arg)
  8. })(3) //输出:3

  (3)带返回值

  1. c := func() int {
  2. fmt.Println(4)
  3. return 5
  4. }
  5. d := c() //打印输出4,并将5赋值给d
  6. fmt.Println(d)

  

二、闭包(closure)

  

  闭包的理解参考:http://www.cnblogs.com/mzwr1982/archive/2012/05/20/2509295.html 

  闭包的用途参考:http://blog.csdn.net/sunlylorn/article/details/6534610

        和   http://www.cnblogs.com/rainman/archive/2009/05/04/1448899.html

  简单来说:

  因为把返回的函数赋给了一个变量,虽然函数在执行完一瞬间会销毁其执行环境,

  但是如果有闭包的话,闭包会保存外部函数的活动对象(变量),所以如果不把对闭包的引用消除掉,

  闭包会一直存在内存中,垃圾收集器不会销毁闭包占用的内存。

    ----来自知乎回答http://www.zhihu.com/question/34649602

  使用举例

  (1)

  1. //函数A是一个不带参数,返回值是一个匿名函数,且该函数
  2. //带有一个int类型参数,返回值为一个int类型
  3. func A() func(aa int) int {
  4. sum := 0
  5. return func(cc int) int {
  6. sum += cc
  7. fmt.Println("aa=", aa, "bb=", bb, " sum=", sum)
  8. return sum
  9. }
  10. }//编译错误,提示aa未定义

  实际上func(aa int) int只是函数A的返回值,在这里给参数取名无任何作用,反而会影响代码阅读,直接用func(int) int 即可。

  更正后:

  1. func A() func(int) int {
  2. sum := 0
  3. return func(bb int) int {
  4. sum += bb
  5. fmt.Println("bb=", bb, "\tsum=", sum)
  6. return sum
  7. }
  8. }

  调用1:

  1. func main() {
  2. a := A()//定义变量a,并将函数A的返回值赋给a
  3. b := a(4)
  4. fmt.Println(b)
  5. }
  6. /*
  7. ** 输出:
  8. ** bb= 4 sum= 4
  9. ** 4
  10. */

  调用2:

  1. func main() {
  2. a := A()
  3. a(0)
  4. a(1)
  5. a(5)
  6. }
  7. /*
  8. **  输出:
  9. **  bb= 0 sum= 0
  10. **  bb= 1 sum= 1
  11. **  bb= 5 sum= 6
  12. */

  以上调用通过闭包实现了sum的累加

  调用3:

  1. func main() {
  2. a := A()
  3. c := A()
  4. a(0)
  5. a(5)
  6. c(10)
  7. c(20)
  8. }
  9. /*
  10. **  输出:
  11. **  bb= 0 sum= 0
  12. **  bb= 5 sum= 5
  13. **  bb= 10 sum= 10
  14. **  bb= 20 sum= 30
  15. */

  可以看出,上例中调用了两次函数A,构成了两个闭包,这两个闭包维护的变量sum不是同一个变量。

  (2)

  1. func B() []func() {
  2. b := make([]func(), 3, 3)
  3. for i := 0; i < 3; i++ {
  4. b[i] = func() {
  5. fmt.Println(i)
  6. }
  7. }
  8. return b
  9. }
  10.  
  11. func main() {
  12. c := B()
  13. c[0]()
  14. c[1]()
  15. c[2]()
  16. }
  17. /*
  18. **  输出:
  19. **  3
  20. **  3
  21. **  3
  22. */

  闭包通过引用的方式使用外部函数的变量。

  上例中只调用了一次函数B,构成一个闭包,i 在外部函数B中定义,所以闭包维护该变量 i ,c[0]、c[1]、c[2]中的 i 都是闭包中 i 的引用。

  因此执行c:=B()后,i 的值已经变为3,故再调用c[0]()时的输出是3而不是0。

  可作如下修改:

  1. func B() []func() {
  2. b := make([]func(), 3, 3)
  3. for i := 0; i < 3; i++ {
  4. b[i] = (func(j int) func() {
  5. return func() {
  6. fmt.Println(j)
  7. }
  8. })(i)
  9. }
  10. return b
  11. }
  12.  
  13. func main() {
  14. c := B()
  15. c[0]()
  16. c[1]()
  17. c[2]()
  18. }
  19. /*
  20. ** 输出:
  21. ** 0
  22. ** 1
  23. ** 2
  24. */

  以上修改可能没有什么实际意义,此处仅为说明问题使用。

  在使用defer的时候可能出现类似问题,需要注意:

  1. for j := 0; j < 2; j++ {
  2. defer (func() {
  3. fmt.Println(j)
  4. })()
  5. }
  6. /*
  7. ** 输出:
  8. ** 2
  9. ** 2
  10. */

  

  

  

  

  

go:匿名函数与闭包的更多相关文章

  1. JavaScript笔记 第十六章 匿名函数和闭包

    1.匿名函数 2.闭包 匿名函数就是没有名字的函数,闭包是可访问一个函数作用域里变量的函数. 一.匿名函数 //普通函数 function getName() { return 'name'; } a ...

  2. 第一百一十节,JavaScript匿名函数和闭包

    JavaScript匿名函数和闭包 学习要点: 1.匿名函数 2.闭包 匿名函数就是没有名字的函数,闭包是可访问一个函数作用域里变量的函数.声明:本节内容需要有面向对象和少量设计模式基础,否则无法听懂 ...

  3. JavaScript(第十五天)【匿名函数和闭包】

      学习要点: 1.匿名函数 2.闭包 匿名函数就是没有名字的函数,闭包是可访问一个函数作用域里变量的函数.声明:本节内容需要有面向对象和少量设计模式基础,否则无法听懂.(所需基础15章的时候已经声明 ...

  4. 从匿名函数(闭包特性)到 PHP 设计模式之容器模式

    匿名函数(匿名函数) 匿名函数,也叫闭包函数,它允许临时创建一个没有指定名称的函数,常用作回调函数参数的值,也可以作为变量的值来使用.具体的使用见以下示例代码: /* 示例一:声明一个简单匿名函数,并 ...

  5. php的匿名函数和闭包函数

    php的匿名函数和闭包函数 tags: 匿名函数 闭包函数 php闭包函数 php匿名函数 function use 引言:匿名函数和闭包函数都不是特别高深的知识,但是很多刚入门的朋友却总是很困惑,因 ...

  6. js匿名函数和闭包总结

    js匿名函数和闭包总结 一.总结 一句话总结:匿名函数的最主要作用是创建闭包,闭包就是将函数内部和函数外部连接起来的一座桥梁.内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕.闭包可以用 ...

  7. 匿名函数、闭包、lambda表达式、Block

    C#有lambda.匿名函数,js有匿名函数.闭包,OC中有block,看到这是不是心中有一万个草泥马在跑,不过它们这些都是换汤不换药,不同语言名字不一样. 从功能性上说lambda和closure( ...

  8. Golang之匿名函数和闭包

    Go语言支持匿名函数,即函数可以像普通变量一样被传递或使用. 使用方法如下: main.go package main import ( "fmt" ) func main() { ...

  9. js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题)

    js循环函数中的匿名函数和闭包问题(匿名函数要用循环中变量的问题) 一.总结 需要好好看下面代码 本质是因为匿名函数用到了循环中的变量,而普通方式访问的话,匿名函数的访问在循环之后,所以得到的i是循环 ...

  10. javascript进阶课程--第三章--匿名函数和闭包

    javascript进阶课程--第三章--匿名函数和闭包 一.总结 二.学习要点 掌握匿名函数和闭包的应用 三.匿名函数和闭包 匿名函数 没有函数名字的函数 单独的匿名函数是无法运行和调用的 可以把匿 ...

随机推荐

  1. LeetCode-66-Plus One

    Given a non-negative number represented as an array of digits, plus one to the number. The digits ar ...

  2. 浅谈微信小程序

    在如火如荼的互联网技术发展中,各种各样的框架出现,当下最受关注的应该就是微信小程序了.从新闻论坛乃至qq群.微信群,很多很多从事IT工作的朋友喜欢讨论研究这个小程序.带着好奇心,我也参与其中. 第一步 ...

  3. Wireshark基本介绍和学习TCP三次握手

    wireshark介绍 wireshark的官方下载网站: http://www.wireshark.org/ wireshark是非常流行的网络封包分析软件,功能十分强大.可以截取各种网络封包,显示 ...

  4. jquery版楼层滚动特效

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>楼 ...

  5. jprofiler_监控远程linux服务器的JVM进程(实践)

    几天前写了一篇文章,jprofiler_监控远程linux服务器的tomcat进程(实践),介绍了使用jprofiler怎样监控远程linux的tomcat进程,这两天想了想,除了可以监控tomcat ...

  6. vim2

    一.光标控制命令   命令                   移动    k                   向上移一行    j                   向下移一行    h    ...

  7. 深入理解图优化与g2o:g2o篇

    内容提要 讲完了优化的基本知识,我们来看一下g2o的结构.本篇将讨论g2o的代码结构,并带着大家一起写一个简单的双视图bundle adjustment:从两张图像中估计相机运动和特征点位置.你可以把 ...

  8. Nginx基本使用

    Nginx基本使用 下载源码包http://nginx.org/ http://nginx.org/en/download.html yum -y install pcre-devel openssl ...

  9. js获取Html元素的实际宽度高度

    第一种情况就是宽高都写在样式表里,就比如#div1{width:120px;}.这中情况通过#div1.style.width拿不到宽度,而通过#div1.offsetWidth才可以获取到宽度. 第 ...

  10. pycloudtag 标签云

    原创,转载请标明 QQ:231469242 # -*- coding: utf-8 -*- """Python3.0 Created on Sat Nov 26 08:5 ...