Go语言函数高级用法(6)| Go主题月

1,149 阅读2分钟

闭包

Go语言的闭包简单来说就是能够读取其他函数内部变量的函数,我们直接先来个例子(完整的):

package main
import "fmt"

func test() func(int) int {
    sum := 10;
    return func (v1 int) int {
        sum += v1;
        return sum
    }
}

func main() {
    //函数也可以当作变量赋值,此时mytest可以叫做‘回调函数’,必须要做这一步,因为test函数没有接收参数,mytest表示接收test函数返回值(返回值是一个匿名函数,可以传参),下面可以传参。
    mytest := test(); //这个时候也可看作已经调用了test函数,sum已经初始化为10
	for i := 0; i<10; i++ {
	    //循环的第一遍,输出10,test里sum = sum+0;循环第二遍,输出11,i为2
	    //依次类推接下来输出13,16,20,25....55
	    //为什么sum每次循环没有被初始化?实际上mytest调用的是里面的匿名函数,没有名字的函数,sum在上面mytest := test();已经初始化了
	    //后面的每一次循环都会使用上次循环计算完的sum,每次循环都会return sum给下次用。
	    fmt.Println(mytest(i));
	}
}

闭包实现了一个匿名函数,test里面return 的函数就是匿名函数,没有函数名。闭包的特点就是匿名函数内部引用了外部函数的参数或变量,sum就是内部函数调用的外部函数的变量,那么假如不用闭包怎么实现这个功能呢?闭包有什么好处呢?我们来写个代码试试:

package main
import "fmt"

func main() {
    sum :=10	
	for i := 1; i <= 10; i++ {
	    sum += i;
		fmt.Println(sum);
	}
}

可以看到此时sum这个变量和闭包里面的sum生命周期就不一样了,闭包匿名函数使用的外部函数变量生命周期随着闭包,没有调用它就被内存回收机制回收了,sum就是局部变量,每次不是复制出来的,所以比第二种快很多,而第二种情况,sum还可以被后面的代码使用,每次都会给sum全局变量重新复制赋值。main函数执行完成才会被回收。

总结

闭包和匿名函数通常是一起用的,今天填了昨天的坑,给大家展示函数如何当作返回值,代码的注释都很多,说得比较通俗详细,可能不是很准确,有任何问题欢迎大家指出。