一、匿名函数

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

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

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

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

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

  使用举例

  (1)

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

  (2)带参数

b := func(arg int) {
fmt.Println(arg)
}
b(2) //输出:2 (func(arg int) {
fmt.Println(arg)
})(3) //输出:3

  (3)带返回值

c := func() int {
fmt.Println(4)
return 5
}
d := c() //打印输出4,并将5赋值给d
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)

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

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

  更正后:

func A() func(int) int {
sum := 0
return func(bb int) int {
sum += bb
fmt.Println("bb=", bb, "\tsum=", sum)
return sum
}
}

  调用1:

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

  调用2:

func main() {
a := A()
a(0)
a(1)
a(5)
}
/*
**  输出:
**  bb= 0 sum= 0
**  bb= 1 sum= 1
**  bb= 5 sum= 6
*/

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

  调用3:

func main() {
a := A()
c := A()
a(0)
a(5)
c(10)
c(20)
}
/*
**  输出:
**  bb= 0 sum= 0
**  bb= 5 sum= 5
**  bb= 10 sum= 10
**  bb= 20 sum= 30
*/

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

  (2)

func B() []func() {
b := make([]func(), 3, 3)
for i := 0; i < 3; i++ {
b[i] = func() {
fmt.Println(i)
}
}
return b
} func main() {
c := B()
c[0]()
c[1]()
c[2]()
}
/*
**  输出:
**  3
**  3
**  3
*/

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

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

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

  可作如下修改:

func B() []func() {
b := make([]func(), 3, 3)
for i := 0; i < 3; i++ {
b[i] = (func(j int) func() {
return func() {
fmt.Println(j)
}
})(i)
}
return b
} func main() {
c := B()
c[0]()
c[1]()
c[2]()
}
/*
** 输出:
** 0
** 1
** 2
*/

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

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

for j := 0; j < 2; j++ {
defer (func() {
fmt.Println(j)
})()
}
/*
** 输出:
** 2
** 2
*/

  

  

  

  

  

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. JS组件系列——封装自己的JS组件,你也可以

    前言:之前分享了那么多bootstrap组件的使用经验,这篇博主打算研究下JS组件的扩展和封装,我们来感受下JQuery为我们提供$.Extend的神奇,看看我们怎么自定义自己的组件,比如我们想扩展一 ...

  2. FPGA与simulink联合实时环路系列——实验一 测试

    实验一 测试 实验内容 在simulink创建测试模块,通过测试模块产生信号,再传送到FPGA,FPGA读出后再将信号无处理传送回simulink进行显示.由此来测试整个硬件在环的功能是否正常,并且熟 ...

  3. 在C#项目中需要用double类型操作MSSQL float类型数据(附C#数据类型和SQL数据类型对照)

    C#操作SQL Float类型,数据会多很多小数,原来是C#的float和sql的float类型不一致.以下是数据库中与C#中的数据类型对照. /// <summary> /// 数据库中 ...

  4. android多线程断点续传下载文件

    一.目标 1.多线程抢占服务器资源下载. 2.断点续传. 二.实现思路. 假设分为三个线程: 1.各个线程分别向服务器请求文件的不同部分. 这个涉及Http协议,可以在Header中使用Range参数 ...

  5. 关于C#中readonly的一点小研究

    可能园子里有不少文章已经说明了这个问题了,但是我在这里写这篇博客只是写写自己的一些体会,也权当是整理归纳,高手莫见笑. ===============正文分割线================== 现 ...

  6. iOS小知识点(UI部分)

    1. 父视图通过Tag来找到UIView UIView *targetView = [superView viewWithTag:10];//只在当前视图以及subviews中找,不能再孙子中找. 2 ...

  7. js点击某个图标或按钮弹出文件选择框

    <HTML> <head> <script type="text/javascript" src="script/jquery-1.6.2. ...

  8. Leetcode 377. Combination Sum IV

    Given an integer array with all positive numbers and no duplicates, find the number of possible comb ...

  9. 非常提高mac生产力的一些插件归纳整理

    1.cheatsheet   快捷键提示插件,下载后按command键3秒,可以显示当前app的所有快捷键. 比如我现在在chrome的界面,按下command三秒,会弹出一个快捷键提示框. 2.Ba ...

  10. asp.net读取execl模板并填充数据,关闭进程

    <head runat="server"> <title></title> <script src="Scripts/jquer ...