1.go语言匿名函数的用法
1-声明一个匿名函数
func(参数列表) 返回值列表 {
函数体...
}
2-匿名函数的调用
package main
import (
"fmt"
)
func main() {
//无参数直接加括号
func() int {
var i int =5
fmt.Printf("func 1\n")
return i
}()
//有参数,在括号里加参数
func(arge int) {
fmt.Printf("func %d\n",arge)
}(2)
//也可以先赋给一个变量再调用
a := func() int {
fmt.Printf("func 3\n")
return 5
}
a()
}
程序输出:
func 1
func 2
func 3
2.一个复杂的例子分析
func main() {
var j int = 5
a := func()(func()) {
var i int = 10
return func() {
fmt.Printf("i, j: %d, %d\n", i, j)
}
}()
a()
j *= 2
a()
}
程序输出:
i, j: 10, 5
i, j: 10, 10
分析:
1---"...func()(func()) {....."
表明此匿名函数返回值的类型是func(), 即此匿名函数返回一个函数指针(此处引用一下c 的概念);
2---"...return func() {
fmt.Printf("i, j: %d, %d\n", i, j)
}..."
表明返回的函数指针指向一个打印 i, j: %d, %d\n 的函数;
3---"...a := func()(func()) {
...
}()..."
末尾的括号表明匿名函数被调用,并将返回的函数指针赋给变量a ;
综合来看:
"...a := func()(func()) {
var i int = 10
return func() {
fmt.Printf("i, j: %d, %d\n", i, j)
}
}()..."
此代码片段的意思"等价于"
a := func() {
fmt.Printf("i, j: %d, %d\n", i, j)
}
至于为何要用匿名函数如此的转一圈,是因为要引用闭包的概念,此概念省略不表,多写点代码试试就能体会了。
####################
在找“闭包”的资料时找到这个:
http://www.cnblogs.com/Jifangliang/archive/2008/08/05/1260602.html
这里解说得很清楚明了,例子也很间单。
闭包是“函数”和“引用环境”组成的整体。
在这里用Go重写一下他的例子:
package main
import "fmt"
func ExFunc(n int) func() {
sum:=n
a:=func () { //把匿名函数作为值赋给变量a (Go 不允许函数嵌套。然而你可以利用匿名函数实现函数嵌套)
fmt.Println(sum+1) //调用本函数外的变量
} //这里没有()匿名函数不会马上执行
return a
}
func main() {
myFunc:=ExFunc(10)
myFunc()
myAnotherFunc:=ExFunc(20)
myAnotherFunc()
myFunc()
myAnotherFunc()
}
这个函数还有另一个写法:
func ExFunc(n int) func() {
sum:=n
return func () { //直接在返回处的匿名函数
fmt.Println(sum+1)
}
}
另一个例子:
package main
import "fmt"
func ExFunc(n int) func() {
return func() {
n++ //这里对外部变量加1
fmt.Println(n)
}
}
func main() {
myFunc := ExFunc(10)
myFunc() //这里输出11
myAnotherFunc := ExFunc(20)
myAnotherFunc() //这里输出21
myFunc()
myAnotherFunc()
//再一次调用myFunc()函数,结果是12,由此得出以下两点
//1.内函数对外函数 的变量的修改,是对变量的引用
//2.变量被引用后,它所在的函数结束,这变量也不会马上被烧毁
}
闭包函数出现的条件:
1.被嵌套的函数引用到非本函数的外部变量,而且这外部变量不是“全局变量”
2.嵌套的函数被独立了出来(被父函数返回或赋值 变成了独立的个体),
而被引用的变量所在的父函数已结束
还找到句明言:对象是附有行为的数据,而闭包是附有数据的行为。