谈谈我所理解的闭包,js、php、golang里的closure

本人开始接触编程是从js开始的,当时网上很多人说闭包是难点,各种地方对闭包的解释也是千奇百怪。如今开始接触js以外的各种编程语言,发现不光是js,php、java、c++等各种编程语言里都有闭包,而且大体意思是差不多的。

js里的闭包

比较权威的高程里是这样解释闭包的:

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另
一个函数。

当初看这个解释有点懵逼,理解成闭包就是函数中的函数了。现在看来感觉有点问题,不知道是不是翻译的问题,全局作用域下的函数不也是闭包吗?

再看下mdn的解释:

Closures (闭包)是使用被作用域封闭的变量,函数,闭包等执行的一个函数的作用域。通常我们用和其相应的函数来指代这些作用域。(可以访问独立数据的函数)

这是啥, 一脸懵逼。

个人理解:闭包就是一个函数,它引用了外部变量,有这两个条件就形成了闭包

在我们日常使用中,外部变量很少是全局变量,经常是用一个母函数return一个子函数,子函数引用母函数中的变量。这个病了因为被引用了,所以母函数执行完它并没有被销毁,成为了自由变量。

php里的闭包

最近不满足于只干前端的活,开始用起了php。php不愧是最好的语言,抄起来就是一梭子。php里也有闭包,下面对比着js来看一下。

php官网对闭包的解释:

匿名函数(Anonymous functions),也叫闭包函数(closures),允许 临时创建一个没有指定名称的函数。最经常用作回调函数(callback)参数的值。

php里的闭包和js其实很像啊,也是和函数有关,其实也是能访问自由变量的函数,常用在回调函数。值得一题的是php的闭包闭的更彻底,他不能主动访问外部变量,而是要主动用use关键词传进去,而且这个传参还是值传递,如果想引用传递还得加上&。

$example = function () {
    var_dump($message);
};

$example = function () use (&$message) {
    var_dump($message);
};

各位觉得php这个设定是多此一举吗?个人觉得这样更保险啊。

Golang里的闭包

最近在学习go语言,让我们来看一下go语言里的闭包。

go的官方教程里如此写道:

Function closures
Go functions may be closures. A closure is a function value that references variables from outside its body. The function may access and assign to the referenced variables; in this sense the function is "bound" to the variables.
For example, the adder function returns a closure. Each closure is bound to its own sum variable.

例子:

package main

import "fmt"

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}

翻译一下:
函数闭包
go中函数可以形成闭包,闭包是返回的函数在函数体外仍引用了其中的变量。作为值返回的函数可以访问和修改引用的变量,在这种情况下,返回的函数和函数体中的变量相互关联。
例子中,adder函数返回一个闭包,每个闭包就与同一个sun变量有关联。

在go中,闭包特指将函数作为值返回的情况,被返回的函数引用了生成它的母函数中的变量。

学习了go里的闭包我感觉自己前面的理解似乎有些问题,所以做了一些修改。

评论里一位大神总结的非常好:

从内存回收角度考虑更容易理解闭包,正常函数调用完后内部的变量就会销毁,但闭包却能使本该销毁的变量一直保留。

reference:
不装逼地解释闭包-方应杭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值