• 技术文章 >后端开发 >Golang

    你知道golang中的闭包的意义和用法吗

    藏色散人藏色散人2020-12-24 15:25:42转载468
    下面由golang教程栏目给大家介绍golang中的闭包的意义和用法,希望对需要的朋友有所帮助!

    什么是闭包?

    Go 函数可以是一个闭包。闭包是一个函数值,它引用了函数体之外的变量。 这个函数可以对这个引用的变量进行访问和赋值;换句话说这个函数被“绑定”在这个变量上。

    我的不靠谱的理解,一个闭包相当于一个类的实例,函数体之外的变量相当于这个实例存储的变量。

    没有闭包的时候,函数就是一次性买卖,函数执行完毕后就无法再更改函数中变量的值(应该是内存释放了);有了闭包后函数就成为了一个变量的值,只要变量没被释放,函数就会一直处于存活并独享的状态,因此可以后期更改函数中变量的值(因为这样就不会被go给回收内存了,会一直缓存在那里)。

    闭包的主要意义

    缩小变量作用域,减少对全局变量的污染。下面的累加如果用全局变量进行实现,全局变量容易被其他人污染。同时,所有我要实现n个累加器,那么每次需要n个全局变量。利用背包,每个生成的累加器myAdder1, myAdder2 := adder(), adder()有自己独立的sum,sum可以看作为myAdder1.sum与myAdder2.sum。

    利用背包可以实现有自身状态的函数

    package mainimport (
    	"fmt")func adder() func(int) int {
    	sum := 0
    	return func(x int) int {
    		sum += x		return sum	}}func main() {
    	myAdder := adder()
    	
    	// 从1加到10
    	for i := 1; i <= 10; i++ {
    		myAdder(i)
    	}
    	
    	fmt.Println(myAdder(0))
    	// 再加上45
    	fmt.Println(myAdder(45))}

    结果:

    55		// 1+...+10
    100

    例子

    利用闭包实现斐波拉契数列

    package mainimport (
    	"fmt")func fibonacci() func() int {
    	b0 := 0
    	b1 := 1
    	return func() int {
    		tmp := b0 + b1
    		b0 = b1
    		b1 = tmp		return b1	}}func main() {
    	myFibonacci := fibonacci()
    	for i := 1; i <= 5; i++ {
    		fmt.Println(myFibonacci())
    	}}

    结果:

    1
    2
    3
    5
    8

    易错点

    func B() []func() {
    	b := make([]func(), 3, 3)
    	for i := 0; i < 3; i++ {
    		b[i] = func() {
    			fmt.Println(i)
    		}
    	}
    	return b}func main() {
    	c := B()
    	c[0]()
    	c[1]()
    	c[2]()}

    结果:

    // 因为都引用i,i最后变成了3
    3
    3
    3

    改正方法1:

    package mainimport (
    	"fmt")func B() []func() {
    	b := make([]func(), 3, 3)
    	for i := 0; i < 3; i++ {
    		j := i
    		b[i] = func() {
    			fmt.Println(j)
    		}
    	}
    	return b}func main() {
    	c := B()
    	c[0]()
    	c[1]()
    	c[2]()}

    改正方法2:

    package mainimport (
    	"fmt")func B() []func() {
    	b := make([]func(), 3, 3)
    	for i := 0; i < 3; i++ {
    		b[i] = func(j int) func(){
    			return func() {
    				fmt.Println(j)
    			}
    		}(i)
    	}
    	return b}func main() {
    	c := B()
    	c[0]()
    	c[1]()
    	c[2]()}

    更多相关技术文章,请访问go语言教程栏目!

    以上就是你知道golang中的闭包的意义和用法吗的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:csdn,如有侵犯,请联系admin@php.cn删除
    专题推荐:go闭包
    上一篇:关于Golang 全局sql数据库连接 下一篇:关于golang cpu性能分析
    大前端线上培训班

    相关文章推荐

    • 详解Golang数组的传递• 如何使用golang的pprof包对程序进行性能分析• Golang怎么执行cmd命令行• 记录Golang Recover的一个小坑• 关于Golang 全局sql数据库连接

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网