前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 编程 | 连载 24 - 闭包 Closure

Go 编程 | 连载 24 - 闭包 Closure

作者头像
RiemannHypothesis
发布2022-09-28 16:12:29
3020
发布2022-09-28 16:12:29
举报
文章被收录于专栏:Elixir

一、闭包 Closure

闭包 Closure 在某些语言如 Java、Python 或者 Ruby 中也被成为 Lambda 表达式或者匿名函数。

闭包是引用了自由变量的 匿名函数,被引用的自由变量和函数一同存在,即使已经离开了自由变量的环境也不会释放或者删除,在闭包中可以继续使用这个变量,也就是说闭包就等于 函数+引用环境

Go 编程 | 连载 23 - 函数实现接口 中,我们知道函数可以通过定义一个函数类型来像结构体一样实例化;函数本身不存储任何信息,只有与引用环境结合后形成的闭包才具有“记忆性”。

函数是编译期静态的概念,而闭包是运行期动态的概念。

闭包可以对作用域上变量的引用进行修改,修改引用的变量就会对变量进行实际修改。

代码语言:javascript
复制
package main

import "fmt"

func main(){

   info := "Go"
   // 将一个匿名函数赋值给 f 变量
   f1 := func(){

      // 修改 info 变量的值
      info = "Elixir"
   }
   // 调用匿名函数
   f1()
   fmt.Println(info)

   stark := make(map[string]interface{})
   stark["name"] = "Tony Stark"
   stark["age"] = 33
   f2 := func() {
      stark["address"] = "NYC"
   }
   f2()
   fmt.Println(stark)
}

执行上述代码,输出结果如下:

代码语言:javascript
复制
Elixir
map[address:NYC age:33 name:Tony Stark]

二、闭包实现生成器

被捕获到比包中的变量让函数本身有了 “记忆”,闭包中的逻辑可以修改捕获的变量的值,变量就会跟随闭包的声明周期一直存在,闭包本身就如同变量一样有了 “记忆”。

代码语言:javascript
复制
package main

import "fmt"

func main() {

   // 创建一个累加器,初始值为 1
   outputSum := OutputSum(1)
   fmt.Println(outputSum())
   fmt.Printf("%p\n", outputSum)

   // 创建一个累加器,初始值为 10
   outputSum2 := OutputSum(10)
   fmt.Println(outputSum2())
   fmt.Printf("%p\n", outputSum2)
}

// 返回值是一个 func() int 类型既一个返回 int 类型的函数
func OutputSum(v int) func() int {

   return func() int {
      v ++
      return v
   }
}

执行上述代码,输出结果如下:

代码语言:javascript
复制
2
0x108b1a0
11
0x108b180

创建的两个函数实例虽然包含的变量不同,但其实是指向同一块内存,闭包会在运行时动态修改变量值。

闭包这种记忆的特性可以用于实现类似工厂模式的生成器。

代码语言:javascript
复制
package main

import "fmt"

func main() {

   genScore := GenScore("Stark")

   // 返回分数信息
   name, score := genScore()

   fmt.Println(name, score)

}

func GenScore(name string) func()(string, int) {

   // score
   score := 90

   return func() (string, int){

      return name, score
   }
}

执行上述代码,输出结果如下:

代码语言:javascript
复制
Stark 90

上述代码中 GenScore 返回值将 name 和 score 两个变量引入匿名函数,从而形成闭包。

闭包还具有一定的封装性,函数外部无法直接访问修改这些匿名函数中引用的变量,这与面向对象中的封装特性相似。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、闭包 Closure
  • 二、闭包实现生成器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档