闭包的价值

    科技2022-07-10  130

    闭包的价值

    什么是闭包

    闭包是由函数以及相关引用环境组合而成的实体,一般通过在匿名函数中引用外部函数的局部变量或包全局变量组成。

    闭包 = 函数+应用环境

    案例

    闭包对闭包外的环境引入是直接引用,编译器检测到闭包,会将闭包引用到外部变量分配到堆上。

    如果函数返回的闭包引用了该函数的局部变量(参数或者函数内部变量):

    * 多次调用该函数,返回的多个闭包所引用的外部变量是多个副本,原因是每次调用函数都会为局部变量分配内存 * 用一个闭包函数多次,如果该闭包修改了其引用的外部变量,则每一次调用该闭包对该外部变量都有影响,因为闭包函数共享外部引用。

    实例如下:

    package main func fa(a int) func(i int) int{ return func(i int) int{ println(&a,a) a = a + i return a } } func main(){ f:=fa(1)//f引用的外部的闭包环境包括本次函数调用的形参a的值1 g:=fa(1)//g引用的外部的闭包环境包括本次函数调用的形参a的值1 //此时f,g引用的闭包环境中的a的值斌不是同一个,而是两次函数调用产生的副本 println(f(1)) //多次调用f引用的是同一个副本a println(f(1)) println(f(1)) //g中的a值仍然是1 println(g(1)) println(g(1)) }

    运行结果:

    0xc00000a028 1 2 0xc00000a028 2 3 0xc00000a028 3 4 0xc00000a040 1 2 0xc00000a040 2 3

    f和g引用的是不同的a

    如果一个函数调用返回的闭包引用修改了全局变量,则每次调用都会影响全局变量。如果函数返回的闭包引用的是全局变量a,则多次调用该函数返回的多个闭包引用的都是同一个a。同理,调用一个闭包多次引用的也是同一个a,此时如果闭包中修改了a值的逻辑,则每次闭包调用都会影响全局变量a的值。使用闭包是为了减少全局变量,所以闭包i引用全局变量不是好的编程方式。

    实例如下:

    var ( a = 0 ) func fa() func(i int) int { return func(i int) int { println(&a,a) a = a+i return a } } func main() { f := fa(); g :=fa(); println(f(1))//1 println(g(1))//2 println(g(1))//3 println(g(1))//4 }

    运行结果:

    0xc2e180 0 1 0xc2e180 1 2 0xc2e180 2 3 0xc2e180 3 4

    闭包的本质

    闭包最初的目的是减少全局变量,在函数调用的过程中隐式地传递共享变量,有其有用的一面;但是这种隐秘的共享变量的方式带来的坏处是不够直接,不够清晰,除非是非常有价值的地方,一般不建议使用闭包。对向是附有行为的是数据,而闭包是附有数据的行为,类定义时以及显式的集中定义了行为,但是闭包中的数据没有显示地集中申明的地方,这种数据和行为耦合的模型不是一种推荐的编程模式,闭包仅仅是锦上添花的东西,不是不可缺少的。

    Processed: 0.015, SQL: 8