举例讲解Go语言中函数的闭包使用

 更新时间:2016年03月31日 16:35:15   作者:叶剑峰  
这篇文章主要介绍了Go语言中函数的闭包使用示例,函数闭包closure是编程语言中十分重要的特性,需要的朋友可以参考下

和变量的声明不同,Go语言不能在函数里声明另外一个函数。所以在Go的源文件里,函数声明都是出现在最外层的。

“声明”就是把一种类型的变量和一个名字联系起来。

Go里有函数类型的变量,这样,虽然不能在一个函数里直接声明另一个函数,但是可以在一个函数中声明一个函数类型的变量,此时的函数称为闭包(closure)。

例:

复制代码 代码如下:

packagemain
 
import"fmt"
 
funcmain(){
    add:=func(baseint)func(int)(int){
        returnfunc(iint)(int){
            returnbase+i
        }
    }
   
    add5:=add(5)
    fmt.Println("add5(10)=",add5(10))
}

 

这个例子唯一的使用价值大概就是用来展示闭包的构建和使用。

add是一个闭包,因为它是无名的函数类型的变量。可以认为它是一个闭包作坊,根据入参返回(生产)一个闭包。这样add5就是使用5作为add的参数得到的一个闭包。

闭包的声明是在另一个函数的内部,形成嵌套。和块的嵌套一样,内层的变量可以遮盖同名的外层的变量,而且外层变量可以直接在内层使用。如add的base参数在return返回的闭包的外层,所以它的值5在add返回并赋值给add5后依旧存在。当add5执行时,参数i可以从这个外层得到的base相加,得到结果15.

个人理解:

其实理解闭包的最方便的方法就是将闭包函数看成一个类,一个闭包函数调用就是实例化一个类。

然后就可以根据类的角度看出哪些是“全局变量”,哪些是“局部变量”了。

比如上例中的adder函数返回func(int) int 的函数

pos和neg分别实例化了两个“闭包类”,在这个“闭包类”中有个“闭包全局变量”sum。所以这样就很好理解返回的结果了。

再来看下面一个例子:

复制代码 代码如下:

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),
          )
     }
}

运行返回结果:

0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90

这个就是Go中的闭包,一个函数和与其相关的引用环境组合而成的实体。

相关文章

  • Go语言中切片使用的注意事项小结

    Go语言中切片使用的注意事项小结

    切片是引用类型,相信对大家来说都不陌生,下面这篇文章主要给大家总结介绍了关于Go语言中切片使用的一些注意事项,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。
    2018-01-01
  • golang gorm学习之如何指定数据表

    golang gorm学习之如何指定数据表

    在sql中首先要指定是从哪张表中查询,所以这篇文章小编就来带大家一起看一下gorm是如何根据model来自动解析表名的,感兴趣的小伙伴可以了解下
    2023-08-08
  • Golang中fsnotify包监听文件变化的原理详解

    Golang中fsnotify包监听文件变化的原理详解

    Golang提供了一个强大的fsnotify包,它能够帮助我们轻松实现文件系统的监控,本文将深入探讨fsnotify包的原理,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-12-12
  • Golang map实践及实现原理解析

    Golang map实践及实现原理解析

    这篇文章主要介绍了Golang map实践以及实现原理,Go 语言中,通过哈希查找表实现 map,用链表法解决哈希冲突,本文结合实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2022-06-06
  • Go语言单向通道的实现

    Go语言单向通道的实现

    本文主要介绍了Go语言单向通道的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • golang通过mysql语句实现分页查询

    golang通过mysql语句实现分页查询

    这篇文章主要介绍了golang通过mysql语句实现分页查询,文章内容介绍详细,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-03-03
  • Go语言实现类似c++中的多态功能实例

    Go语言实现类似c++中的多态功能实例

    Go本身不具有多态的特性,不能够像Java、C++那样编写多态类、多态方法。但是,使用Go可以编写具有多态功能的类绑定的方法。下面来一起看看吧
    2016-09-09
  • 教你用go语言实现比特币交易功能(Transaction)

    教你用go语言实现比特币交易功能(Transaction)

    每一笔比特币交易都会创造输出,输出都会被区块链记录下来。给某个人发送比特币,实际上意味着创造新的 UTXO 并注册到那个人的地址,可以为他所用,今天通过本文给大家分享go语言实现比特币交易功能,一起看看吧
    2021-05-05
  • Golang判断struct/slice/map是否相等以及对比的方法总结

    Golang判断struct/slice/map是否相等以及对比的方法总结

    平时开发中对比两个struct或者map、slice是否相等是经常遇到的,有很多对比的方式,比如==,reflect.DeepEqual(),cmp.Equal()等也是经常容易混淆的,这么多种对比方式,适用场景和优缺点都有哪些呢?今天我们来具体总结一下,感兴趣的小伙伴们可以参考借鉴
    2022-11-11
  • golang中拿slice当queue和拿list当queue使用分析

    golang中拿slice当queue和拿list当queue使用分析

    这篇文章主要为大家介绍了golang 中拿slice当queue和拿list当queue使用分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论