拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这 一限制,在任何表达式中表示一个函数值。函数字面量的语法和函数声明相似,区别在于func关键字后 没有函数名。函数值字面量是一种表达式,它的值被成为匿名函数(anonymous function)。 (摘自Go语言圣经)
匿名函数直接插入代码中
func main() { for i := 0; i < 3; i++ { //三次输出值相同,都是1 fmt.Println(func() int { //A函数可以作为B函数的输入,逻辑是A的返回值作为B的输入参数 var x int //传入值为函数(实际上是函数指针)的行为称为回调 x++ return x * x }()) // 记得匿名函数后加上括号,作为这个匿名函数的传入参数, } //这个匿名函数不接受参数,加上空括号即可 }
匿名函数赋给变量后调用
func squares() func() int {//返回值是一个函数指针,这里是匿名函数的指针,int是匿名函数返回值 return func() int { var x int x++ return x * x } } func main() { f := squares() //调用squares,返回的指向匿名函数的指针赋给f fmt.Println(f()) // 利用f 间接调用匿名函数 fmt.Println(f()) // 输出值都是"1" fmt.Println(f()) // "1" }
匿名函数和闭包
func squares() func() int { var x int //注意这里和上面不同,x定义在匿名函数外面,默认值为0 return func() int { x++ return x * x } } func main() { f := squares()//调用squares形成闭包,闭包中包括一个变量x和匿名函数,赋给f fmt.Println(f()) // 输出"1",语句结束后x=1,并带入下一句 fmt.Println(f()) // "4",闭包中变量x在f被销毁前都有效,并不断被匿名函数更新值 fmt.Println(f()) // "9" //g := squares() 创建一个新的闭包,它里面的x=0 }
@end
```
最后附上GitHub:https://github.com/gonearewe