函数:闭包以及实现

闭包是指匿名函数引用其上下文环境的一种状态。它由函数和环境变量两部分组成,导致环境变量生命周期延长并可能引发数据竞争。闭包实现中,函数返回时将匿名函数和环境变量保存在堆上,使得即使函数执行结束,引用的值依然有效。在并发情况下,多个闭包对同一环境变量的操作可能导致数据竞争,需注意加锁处理。
摘要由CSDN通过智能技术生成

何为闭包

一个匿名函数引用了它的上下文对象,我们把这种状态称之为闭包。

func test(x int) func() {
    println("test.x :", &x)

    return func() {
        println("closure.x :", &x, x)
    }
}

func main() {
    f := test(100)
    f()
}

和匿名函数关系最深的就是闭包,因为匿名函数可以当做返回值来传。

func test() func() {
    x := 1 //局部变量
    fmt.Printf("%p: %v\n", &x, x) //输出地址
    //返回函数
    return func() {
        fmt.Printf("%p: %v\n", &x, x)
    }
}

func main() {
    f := test()
    f()
}

调用f()test栈帧已经失效,但可以打印x的值,这涉及到闭包是由两部分组成,匿名函数的指针加上环境变量的指针。很显然x必须逃逸到堆上才能在f()访问。因为堆上的对象和栈帧没有关系由GC来控制,这就会涉及到逃逸的问题。

$ go build -gcflags "-m -l" main.go

闭包通过指针引用环境变量

闭包严格意义上来说,由两个东西组成的,函数加上环境变量,称之为闭包。闭包有这样一个问题,比如说有一个函数,函数内部有个环境变量x&#x

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包在编程中有很多应用场景,以下是一些常见的例子: 1. 数据封装和私有变量:闭包可以用来创建私有变量,从而实现数据封装和保护。这在模块化编程和面向对象编程中非常有用。 2. 函数工厂:闭包可以用来创建一系列相关的函数,这些函数共享相同的外部变量。这在创建类似于Python中的装饰器或JavaScript中的高阶函数时非常有用。 3. 延迟执行和计时器:闭包可以用来实现延迟执行和定时器功能。例如,在JavaScript中,setTimeout和setInterval函数使用闭包实现延迟执行和定时器功能。 4. 记忆化(Memoization):闭包可以用来实现记忆化,即缓存函数的计算结果,以便在后续调用中重用。这可以提高函数的性能,特别是在处理计算密集型任务时。 5. 事件处理和回调函数:在JavaScript等事件驱动的编程环境中,闭包常用于实现事件处理和回调函数闭包可以捕获事件处理函数的上下文,使得事件处理函数可以访问其所需的外部变量。 6. 部分应用(Partial Application)和柯里化(Currying):闭包可以用来实现部分应用和柯里化,这是一种将多参数函数转换为一系列单参数函数的技术。这可以简化函数调用,使得代码更加简洁和可读。 7. 实现迭代器和生成器:在某些编程语言中,例如Python和JavaScript,闭包可以用来实现迭代器和生成器,这是一种用于遍历数据结构的高效方法。
最新发布
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值