专栏首页aoho求索夯实基础:Go 语言匿名函数和闭包的应用实践

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

前文回顾

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

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

匿名函数和闭包

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

func(params)(return params){
 function body
}

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

func (name string){
 fmt.Println("My name is ", name)
}("王小二")

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

currentTime := func() {
 fmt.Println(time.Now())
}
// 调用匿名函数
currentTime()

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

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

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

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

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

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

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 语言入门系列:列表与字典

本文分享自微信公众号 - aoho求索(aohoBlog),作者:cangwu

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-22

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Go 语言基础入门教程 —— 函数篇:匿名函数和闭包

    熟悉 Laravel 框架(一个 PHP Web 框架)的同学对匿名函数应该很熟悉,Laravel 框架中有着大量匿名函数的应用场景,比如路由定义、绑定实现到接...

    学院君
  • 夯实基础:Go 语言结构体和方法的应用实践

    前面的文章主要介绍了 Go 语言中函数和接口相关的使用实践。与 C 语言类似,Go 语言 提供结构体类型。结构体作为一种复合类型,由多个字段组成,每个字段都具备...

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

    前面的文章主要介绍了 Go 语言中提供的常用容器,包括数组、切片,列表和字典等,还介绍了这些容器的遍历方法。本文开始将会介绍 Go 语言中相关的函数和接口。

    aoho求索
  • 一篇文章带你了解Go语言基础之函数(下篇)

    Hey,大家好呀,我是星期八,这次咱们来学习一下函数的最后一些知识,快来上车叭。之前已经分享了:一篇文章带你了解Go语言基础之函数(上篇)、一篇文章带你了解Go...

    Python进阶者
  • go 学习笔记之仅仅需要一个示例就能讲清楚什么闭包

    本篇文章是 Go 语言学习笔记之函数式编程系列文章的第二篇,上一篇介绍了函数基础,这一篇文章重点介绍函数的重要应用之一: 闭包

    雪之梦技术驿站
  • Go语言学习路线 - 4.入门篇:快速体系化地入门Go语言

    如今互联网资料泛滥,入门编程语言的途径有很多种选择,但如果要我推荐,只有一个建议 - 研读一本该编程语言最优秀的基础书籍。

    junedayday
  • 人生人生苦短,Let's Go !!!

    函数既可以接受可变参数也可以接受固定参数,接受可变参数时放在函数的最后,固定参数当然是必须传值的,go语言中没有默认参数

    疯狂的KK
  • 6.824 2020 视频笔记二:RPC和线程

    MIT 今年终于主动在 Youtube 上放出了随堂视频资料,之前跟过一半这门课,今年打算刷一下视频,写写随堂笔记。该课程以分布式基础理论:容错、备份、一致性为...

    青藤木鸟
  • 三分钟学 Go 语言——函数深度解析(中)

    上回函数深度解析给大家聊了一些函数的基本知识,不知道还有没有人记得,不记得赶紧回去复习!

    机智的程序员小熊
  • 【Go语言学习】匿名函数与闭包

    入坑 Go 语言已经大半年了,却没有写过一篇像样的技术文章,每次写一半就搁笔,然后就烂尾了。

    弗兰克的猫
  • 第六章 函数式编程

    1. 函数是组织好的、可重复使用的、用于执行指定任务的代码块。Go语言中支持函数、匿名函数和闭包,并且函数在Go语言中属于“一等公民”。

    用户7798898
  • Go的闭包看你犯错,但Rust的lifetime却默默帮你排坑

    闭包(Closure)在某些编程语言中也被称为 Lambda 表达式,是能够读取其他函数内部变量的函数。一般只有函数内部的子函数才能读取局部变量,所以闭包这样一...

    beyondma
  • Golang之匿名函数和闭包

     基本概念 闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者 任何全局上下文中定义,而是在定义代码块的环境中定义。要执行的代码块...

    超蛋lhy
  • Go语言入门——基础语法篇(二)

    Go的语句是可以省略;结束符的,且每行尽可能只写一句代码,这是Go语言的编程范式,因此应遵循规范,不要加分号。分号只在一种情况下是必须的,当一行写了多个代码语句...

    arcticfox
  • Go语言核心编程(2)——函数

    首字母大小写决定函数在其他包的可见性,大写时其他包可见,小写时只有相同的包可以访问。 多个相邻的同类型的参数可以使用简写模式 不支持默认参数 不支持函数重...

    羊羽shine
  • 【初识Go】| Day7 函数

    这个函数传递了两个参数,分别为num1与num2,并且他们都为int类型,将相加后的结果进行返回。

    yussuy
  • 全网最通透的“闭包”认知 · 跨越语言

    1. 以面试题 · 投石问路 2. 以C#闭包 · 庖丁解牛 3. 跨越语言 ·追本溯源 • 头等函数 •自由变量 •词法作用域4. ...

    有态度的马甲
  • Golang语言情怀-第7期 Go 语言函数

    函数是基本的代码块,用于执行一个任务。Go 语言最少有个 main() 函数。你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。函数声明告诉了编译...

    李海彬
  • golang教程

    这里有两个关键点。 - 其一是defer关键字。defer语句的含义是不管程序是否出现异常,均 在函数退出时自动执行相关代码。 - 其二是Go语言的函数允许返回...

    陨石坠灭

扫码关注云+社区

领取腾讯云代金券