Go 语言中的闭包

本文主要介绍 Go 语言中的闭包。简单的说 Go 语言的闭包就是一个引用了外部自由变量匿名函数,被引用的自由变量和该匿名函数共同存在,不会因为离开了外部环境就被释放或者删除,还可以在这个匿名函数中继续使用。

 

1. Go 语言的匿名函数

在上文中我们了解到了一个新的词汇——匿名函数,我们先来学习一下Go语言中的匿名函数,再来了解在 Go 语言中如何使用闭包。匿名函数,顾名思义,就是隐藏函数名的函数。

代码示例

代码块
  • package main
  • 2
  • import (
  • 4          "fmt"
  • )
  • 6
  • var f = func() {
  • 8          fmt.Println("匿名函数作为变量来使用")
  • }
  • 10
  • 11  func main() {
  • 12          f()
  • 13
  • 14           func(){
  • 15                  fmt.Println("匿名函数直接使用")
  • 16          }()
  • 17  }
  • 第7~9行:定义一个函数类型,值为一个匿名函数的变量;
  • 第 12 行:使用这个匿名函数;
  • 第 14~16 行:定义一个匿名函数。在这个函数后加上(),就可以直接使用这个匿名函数。

执行结果

图片描述

 

2. 匿名函数引用外部变量

如果在匿名函数内,使用了外部环境的变量,就构成了一个闭包。简单来讲就是一个函数内,使用匿名函数来操作函数内声明的变量。

代码示例

代码块
  • package main
  • 2
  • import (
  • 4          "fmt"
  • )
  • 6
  • func main() {
  • 8          str := "Hello World!"
  • 9          func() {
  • 10                str = "Hello Codey!"
  • 11        }()
  • 12        fmt.Println(str)
  • 13  }
  • 第 10 行:匿名函数直接操作了main函数之中的变量str,将其修改为了"Hello Codey!";
  • 第 12 行:输出变量的值。

执行结果

图片描述

上述例子简单的构造了一个闭包,在匿名函数中并没有声明或者定义str这个变量,但是可以直接操作,就是引用可main函数中的自由变量。这个例子可能对自由变量的引用表现不是很直观,我们接下来使用defer和闭包相结合,深入了解一下闭包中的引用外部变量。

代码示例

代码块
  • package main
  • 2
  • import (
  • 4          "fmt"
  • )
  • 6
  • func main() {
  • 8          str := "Hello World!"
  • 9          defer func() {
  • 10                fmt.Println("defer str=", str)
  • 11        }()
  • 12        str = "Hello Codey!"
  • 13        fmt.Println("main str=", str)
  • 14  }

执行结果

图片描述

从执行结果上来看应该是蛮出人意料的,因为前文介绍 defer 的时候明确介绍了 defer 后变量是保留它在 defer 时的值,而不会被 defer 之后的代码所改变。但是在闭包这边这个看起来不太适用,其实是适用的,只是闭包是引用了这个变量,也就是说,在 defer 时被保留下来的是这个变量的地址,后续代码改变的不是地址,而是这个地址存储的值,所以后续代码对这个变量的操作,都会反应到这个 defer 中。

Tips:关于变量的地址,在后续的Go语言的指针中会有详细的介绍。

 

3. 小结

本文主要介绍了 Go 语言中闭包的使用,需要注意以下几点:

  • 闭包就是匿名函数引用外部变量
  • 闭包中引用的变量会被外部环境改变,同时闭包内对变量的改变也会影响到外部环境的使

文章来源于网络,侵删!

相关新闻

历经多年发展,已成为国内好评如潮的Linux云计算运维、SRE、Devops、网络安全、云原生、Go、Python开发专业人才培训机构!