Golang闭包的典型应用
简介:
参考博客:
- https://www.calhoun.io/5-useful-ways-to-use-closures-in-go/
隔离数据
使用这种方式可以隔离不想让调用者的数据,输出指定的结果;或者我们想要计算函数调用的次数。
函数计数器:
// 函数计数器
func counter(f func()) func() int { n := 0return func() int {f()n += 1return n}
}// 测试的调用函数
func foo() {fmt.Println("call foo")
}func main() {cnt := counter(foo)cnt()cnt()cnt()fmt.Println(cnt())
}
/*
输出结果:
call foo
call foo
call foo
call foo
4
*/
counter
可以接受任何输入值和返回值为空的函数,同时返回一个闭包,在这里闭包的结果是函数的调用次数。本例子中,只用cnt
对闭包的引用结束后,才会销毁闭包。一个闭包只有没有外界引用时,才会连同状态一起被销毁。如果记录需要参数的函数,需要单独给counter
传递需要传递的参数类型。
斐波那契数列:
func makeFibGen() func() int {f1 := 0f2 := 1return func() int {f2, f1 = f1+f2, f2return f1}
}func main() {gen := makeFibGen()for i := 0; i < 10; i++ {fmt.Println(gen())}
}
/*
输出结果:
1
1
2
3
5
8
13
21
34
55
*/
代码理解:makeFibGen()
返回的是一个闭包,这是表示斐波那契数列执行到了第几个了,闭包给的结果是第i
项数列的结果。
装饰函数和创建中间件
函数是Go语言的一等公民,可以作为函数的参数进行传递。装饰器和中间件指的就是函数作为参数进行传递的情况。
func wrapping(f func() string) {fmt.Println("do my work...")fmt.Println("wrapping function: ", f())fmt.Println("my work finished !")
}func sayHello() string {return "Hello !"
}func sayByeBye() string {return "Bye Bye !"
}func main() {wrapping(sayHello)wrapping(sayByeBye)
}
/*
输出:
do my work...
wrapping function: Hello !
my work finished !
do my work...
wrapping function: Bye Bye !
my work finished !
*/
一个函数可以根据传递进来的不同的函数产生不同的反应,传递进来的函数本质上是一个闭包。
Defer Work
这一个过程主要是与Javascript的回调函数进行对比,比如在JS中:
doWork1(a, b, function(result) {doWork2(result, function(result) {doWork3(result, function(result) {// use the final result here});});
});
console.log("hi!");
doWork1
函数回调doWork2
,而doWork2
函数回调doWork3
,执行顺序是doWork1
->doWork2
->doWork3
,但是后一步的函数需要用到前一个函数的状态,根据前一个函数的处理结果进行相应的处理。
而在Go语言,直接使用闭包进行解决:
go func() {result := doWork1(a, b)result = doWork2(result)result = doWork3(result)// Use the final result
}()
fmt.Println("hi!")
闭包可以很好保存程序运行的状态,而且让程序的逻辑更加清晰。
Golang闭包的典型应用相关推荐
- Golang闭包陷阱
golang闭包陷阱本质原理其实是range陷阱:Golang for range陷阱 ep 1 func main() {var values = []int{1, 2, 3, 4, 5}for _ ...
- golang 闭包函数的应用技巧
一.有名函数和匿名函数 函数变量类型初始值为nil.函数字面量类型的语法表达格式是 func (InputTypeList) OutputTypeList //无参函数 func fun() { } ...
- golang关于闭包
Golang:"闭包(closure)"到底包了什么? golang 闭包 Golang中闭包的理解 什么是闭包呢?摘用Wikipedia上的一句定义: a closure is ...
- golang学习之四:闭包、defer
golang闭包.defer 闭包 闭包以引用的方式捕捉外部变量 闭包变量与作用域 传统函数局部变量 闭包的变量 defer 延迟:在函数执行完毕之前调用 多个defer执行顺序 闭包 闭包以引用的方 ...
- golang 切片 接口_Golang简单入门教程——函数进阶使用
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第八篇,我们来聊聊golang当中的函数. 我们在之前的时候已经介绍过了函数的基本用法,知道了怎么样设计或者是定义一 ...
- golang 定义一个空切片_Golang简单入门教程——函数进阶使用
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是golang专题的第八篇,我们来聊聊golang当中的函数. 我们在之前的时候已经介绍过了函数的基本用法,知道了怎么样设计或者是定义一 ...
- Deep Learning部署TVM Golang运行时Runtime
Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...
- PHP性状闭包,PHP 闭包及Closure类
原标题:PHP 闭包及Closure类 匿名函数 实现一个简单的匿名函数: $func = function { echo "this is a funcn"; }; 上面就是一个 ...
- JavaScript闭包详解及案例
JavaScript闭包详解及案例 一. 变量作用域 函数内部可以使用全局变量 函数外部不可以使用局部变量 当函数执行完毕时,本作用域内的局部变量会被销毁 二. 闭包 闭包:有权访问另一个函数作用域中 ...
最新文章
- windows 计划任务备份oracle数据库
- lua c语言混合编程入门
- 新买的笔记本电脑怎么分盘_别再吐槽游戏本越玩越慢:笔记本电脑降速揭秘+散热维护小贴士...
- jdbctypetimestamp_mysql之TIMESTAMP(时间戳)用法详解
- Java基础学习总结(49)——Excel导入导出工具类
- 通过xsl显示和输出XML数据
- RISC-V学习资料:《手把手教你设计CPU——RISC-V处理器》
- vue 初识MVC与MVVM,及其与vue基本代码之间的关系
- java ojdbc6_JAVA JDBC在连接ORACLE数据库时出现ojdbc6.jar has no source 问题?
- grads插值_grads各类参数设置.pptx
- ios8正式版固件开放下载 有哪些亮点?
- fgo日服服务器维护,【FGO日服】活动维护公告(10/25)
- CodeForces - 863B-Kayaking(暴力)
- CERT_HAS_EXPIRED
- 虚幻引擎之自定义着色模型(ShadingModel)
- 裸金属服务器能虚拟化吗,裸金属服务器虚拟化概述
- 图像的二维频谱图的理解 20170622
- ksoftirqd内核线程
- Javascript 将阿拉伯数字转换成罗马数字
- 在查找预编译头时遇到意外的文件结尾 是否忘记了向源中添加 include StdAfx h
热门文章
- 平昌一中高考2021成绩查询,2019年四川省平昌中学高考喜报
- java根据父类找子类_在java中实现多态时,可以通过父类变量引用子类的对象。_学小易找答案...
- python网络爬虫学习笔记(三):urllib库的使用
- SAST算法的学习笔记
- 解决ubuntu中出现:dpkg: error processing package install-info
- tensorflow没有代码提示的问题
- 东大OJ 2SAT 异或
- Spring框架XML配置文件使用外部Bean属性注入
- 深度学习之RNN、LSTM、GRU篇
- 剑指 Offer 58 - I. 翻转单词顺序 (双指针)