浅析Go语言中闭包的使用
作者:甜点cc 发布时间:2024-02-16 12:35:18
闭包基本介绍
闭包就是 一个函数 和其相关的 引用环境 组合的一个整体
好处: 保存引用的变量,下次继续使用,不会销毁
下面通过闭包的方式,写一个数字累加器,体验一下闭包的妙处
闭包实现数字累加
package main
import "fmt"
// 累加器
// 闭包 - 函数柯里化
// 返回值类型: func(int) int
func AddUpper() func(int) int {
var n int = 100
return func(i int) int {
n = n + i
return n
}
}
func main() {
f := AddUpper()
fmt.Println(f(1)) // 101
fmt.Println(f(2)) // 103
fmt.Println(f(3)) // 106
}
代码说明
1.AddUpper是一个函数,返回的数据类型 func(int) int
2.闭包的说明
返回的是一个匿名函数,但是这个匿名函数引用到了函数外的变量 n ,因此这个匿名函数就和 n 形成一个整体,构成闭包
3.当反复调用 f
函数时,因为 n 只初始化一次,保存了变量的值,因此每调用一次就相当于进行了累加。
4.我们要搞清楚闭包,关键就是要分析返回的函数使用到哪些变量
代码分析
这里我引入了一个字符串变量str
,来帮助分析闭包是怎么保存变量的。
package main
import (
"fmt"
)
// 累加器
// 闭包 - 函数柯里化
// 返回值类型: func(int) int
func AddUpper() func(int) int {
var n int = 100
var str = "hello"
return func(i int) int {
n = n + i
fmt.Println("i=", i)
str += string(36) // ascii 36 = '$'
fmt.Printf("str==%s\n", str)
return n
}
}
func main() {
f := AddUpper()
// fmt.Println(AddUpper()(1)) // 101
fmt.Println("f(1)=", f(1)) // 101
fmt.Println("f(2)=", f(2)) // 103
fmt.Println("f(3)=", f(3)) // 106
}
i= 1
str==hello$
f(1)= 101
i= 2
str==hello$$
f(2)= 103
i= 3
str==hello$$$
f(3)= 106
从输出可以看出来,闭包引用的变量n
和str
并没有在调用函数的时候重复声明,而是保留了下次函数调用后更新的值。
闭包案例
需求:
编写一个函数 makeSuffix(suffix string) ,可以接收一个文件后缀名,并返回一个闭包
调用闭包,可以传入一个文件名,如果该文件名没有指定后缀,则返回 文件名.jpg ,如果已经有.jpg,则返回原文件名。
strings.HasSuffix,该函数可以判断某个字符串是否有指定的后缀。
上代码
package main
import (
"fmt"
"strings"
)
func makeSuffix(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
// 传统写法
func makeSuffixV2(suffix string, name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
func main() {
// 闭包调用
f := makeSuffix(".jpg")
fmt.Println(f("xiao")) // xiao.jpg
fmt.Println(f("xiaoxiao.jpg")) // xiaoxiao.jpg
fmt.Println(f("xiaoxiao.666")) // xiaoxiao.666.jpg
// 传统写法调用
fmt.Println("makeSuffixV2=", makeSuffixV2(".jpg", "allblue")) // makeSuffixV2= allblue.jpg
fmt.Println("makeSuffixV2=", makeSuffixV2(".jpg", "all.blue")) // makeSuffixV2= all.blue.jpg
}
代码说明
返回的匿名函数和 makeSuffix(suffix string) 的 suffix 变量组合成一个闭包
传统写法和闭包写法实现效果一样,但是,传统写法需要重复写变量, 比如上面的
makeSuffixV2(".jpg", "all.blue"))
闭包则解决了这个问题,是代码看起来更加的简洁
闭包的好处之一: 参数复用
好处: 保存引用的变量,下次继续使用,不会销毁
来源:https://www.cnblogs.com/all-smile/p/16954994.html


猜你喜欢
- 1. 集合 set 简介集合的最大特征是其每个元素都是唯一的,它可以删除、可以增加、也可以通过增删实现替换元素,但是它是没有下标的,你无法通
- RocketMQ 是什么Github 上关于 RocketMQ 的介绍:RcoketMQ 是一款低延迟、高可靠、可伸缩、易于使用的消息中间件
- 设置密码保护SqlServer数据库备份文件! 备份SqlServer数据库 Backup Database [数据库] To disk=&
- 存储过程采用的是select top 加 not in的方式完成,速度也算是相当快了 我测试过了百万级数据量一般查询在1秒一下,贴出来大家交
- /** * 获取地址栏参数 * * @example GetUrlString('id
- 1. 页面在手机端不能上下滑动,在PC端浏览器正常滑动说明:在设置了overflow:auto;属性的前提下,H5页面在PC端浏览器里展示可
- 效果如下所示:# -*- coding: utf-8 -*-import turtle# 绘制太极图函数def draw_TJT(R):&n
- 【源码GitHub地址】:点击进入1. 问题描述之前写了一篇关于《pytorch Dataset, DataLoader产生自定义的训练数据
- 由于Caffe使用的存储图像的数据库是lmdb,因此有时候需要对lmdb文件进行操作,本文主要讲解如何用Python合并lmdb文件。没有l
- 网上关于Python的音视频播放示例都集中在简单的多媒体库或者PyGame这样的游戏库,有些库使用简单,但功能单一,有些库功能丰富,支持的格
- binlog介绍binlog,即二进制日志,它记录了数据库上的所有改变.改变数据库的SQL语句执行结束时,将在binlog的末尾写入一条记录
- smtp是直接调用163邮箱的smtp服务器,需要在163邮箱中设置一下。outlook发送就是Python直接调用win32方式。调用程序
- 在Python中定义一个数据便在内存中开辟一片空间来存储这个变量的值,这块已经被分配的内存空间便会有一个内存地址。访问这块内存需要用到变量名
- 连接mysql常用工具mysql作为数据库服务器来运行,任何满足mysql通信规范的软件都可以作为客户端来连接服务器。常用的客户端:navi
- 一:命名空间里的namespace关键字和__NAMESPACE__常量的运用PHP支持两种抽象的访问当前命名空间内部元素的方法,__NAM
- 一、逻辑回归1.模型的保存与加载模型训练好之后,可以直接保存,需要用到joblib库。保存的时候是pkl格式,二进制,通过dump方法保存。
- 目前 Linux 下有一些使用 Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件系统安全监控软件)、
- 说明: (1)Linux版本Linux version 2.6.32.12-0.7-default (geeko@buildhost) (g
- 本文实例为大家分享了pycharm实现猜数游戏的具体代码,供大家参考,具体内容如下1. 设计界面如下所示,利用QTdesigner设计的界面
- 很久以前我们在写sql的时候,最怕的一件事情就是sql莫名奇妙的超级慢,慢的是撸一管子回来,那个小球还在一直转。。。这个着急也只有当事人才明