前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >夯实基础:Go 语言匿名函数和闭包的应用实践

夯实基础:Go 语言匿名函数和闭包的应用实践

作者头像
aoho求索
发布2021-09-02 09:50:23
9270
发布2021-09-02 09:50:23
举报
文章被收录于专栏:aoho求索

前文回顾

前面的文章主要介绍了 Go 语言中函数声明和参数传递。本文将会继续介绍匿名函数和闭包相关的概念以及使用方法。

匿名函数没有函数名,只有函数体,它只有在被调用的时候才会被初始化。匿名函数一般被当作一种类型被赋值给类型为函数类型的变量,经常用于实现回调函数和闭包等功能。

匿名函数和闭包

Golang 的匿名函数的声明样式如下所示:

代码语言:javascript
复制
func(params)(return params){
 function body
}

匿名函数的声明与普通函数的定义基本一致,除了没有名字之外。我们可以在匿名函数声明之后直接调用它,如下例子所示:

代码语言:javascript
复制
func (name string){
 fmt.Println("My name is ", name)
}("王小二")

在声明匿名函数之后,在其后加上调用的参数列表,即可立即对匿名函数进行调用。除此之外,我们还可以将匿名函数赋值给函数类型的变量,用于多次调用或者求值,如下例子所示:

代码语言:javascript
复制
currentTime := func() {
 fmt.Println(time.Now())
}
// 调用匿名函数
currentTime()

上述例子中,我们通过匿名函数实现了一个简单的报时器,并赋值给 currentTime,每次调用 currentTime,我们都能知道当前系统的最新时间。

匿名函数一个比较常用的场景是用作回调函数。我们在接下来的例子中定义这样一个函数:它接受 string 和匿名函数的参数输入,然后使用匿名函数对 string 进行处理,代码如下所示:

代码语言:javascript
复制
package main

import "fmt"

func proc(input string, processor func(str string))  {
 // 调用匿名函数
 processor(input)
}

func main()  {
 proc("王小二", func(str string) {
  for _, v := range str{
   fmt.Printf("%c\n", v)
  }
 })
}

上面代码中的匿名函数被作为回调函数用于对传递的字符串进行处理,用户可以根据自己的需要传递不同的匿名函数实现对字符串进行不同的处理操作。

闭包是携带状态的函数,它是将函数内部和函数外部连接起来的桥梁。通过闭包,我们可以读取函数内部的变量。我们也可以使用闭包封装私有状态,让它们常驻于内存当中。

闭包能够引用其作用域上部的变量并进行修改,被捕获到闭包中的变量将随着闭包的生命周期一直存在,函数本身是不存储信息的,但是闭包中的变量使闭包本身具备了存储信息的能力。我们可以用闭包的特性实现一个简单的计数器,代码如下所示:

代码语言:javascript
复制

package main

import "fmt"

func createCounter(initial int) func() int {

 if initial < 0{
  initial = 0
 }

 // 引用 initial,创建一个闭包
 return func() int{
  initial++
  // 返回当前计数
  return initial;
 }

}

func main()  {

 // 计数器 1
 c1 := createCounter(1)

 fmt.Println(c1()) // 2
 fmt.Println(c1()) // 3

 // 计数器 2
 c2 := createCounter(10)

 fmt.Println(c2()) // 11
 fmt.Println(c1()) // 4

}

createCounter 函数返回了一个闭包,该闭包中封装了计数值 initial,从外部代码根本无法直接访问该变量。不同的闭包之间变量不会互相干扰,c1c2 两个计数器都是独立进行计数。

小结

本文主要介绍了匿名函数和闭包。在 Go 语言中,函数可以像普通变量一样被传递或使用,这与 C 语言的回调函数比较类似。不同的是,Go 语言支持随时在代码里定义匿名函数。而 Go 的匿名函数是一个闭包。闭包可以作为函数对象或者匿名函数,对于类型系统而言,这意味着不仅要表示数据还要表示代码。

推荐阅读

夯实基础:Go 语言函数声明和参数传递

Go 语言入门系列:列表与字典及其遍历

利用火焰图对 Go 程序进行性能分析

Go 语言入门系列:列表与字典

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 aoho求索 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前文回顾
  • 匿名函数和闭包
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档