5.4 Go 闭包
5.4 Go 闭包
闭包(closure):是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)

package main import (
"fmt"
) //是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)
//函数addUpper返回值是个函数
//返回值是匿名函数 func(int)int
func test() func(int) int {
//定义一个局部变量
n := 10
//返回一个匿名函数
return func(x int) int {
n += x
return n
} } /*
addUpper函数返回了一个匿名函数,这个匿名函数又引用了函数外的变量n,因此匿名函数+n组成了一个整体,形成闭包
当调用f函数时,n仅仅被初始化一次,因此每次调用形成累计 */ func main() {
//调用addUpper函数,获取返回值
f := test()
//此时f是匿名函数,对其传参调用
fmt.Println(f(50)) //10+50=60
fmt.Println(f(20)) //60+20=80
fmt.Println(f(20)) //80+20=100 同一个f对象,保留了n的值 f1 := test()
fmt.Println(f1(10))
}
闭包代码修改
package main import (
"fmt"
) //是由一个函数和其相关的引用环境组合的一个整体。(闭包=函数+引用环境)
//函数addUpper返回值是个函数
//返回值是匿名函数 func(int)int
func test() func(int) int {
//定义一个局部变量
n := 10
var str = "oldboy"
//返回一个匿名函数
return func(x int) int {
n += x
str += string(36) //36对应的
fmt.Println("此时str值:", str)
return n
} } /*
addUpper函数返回了一个匿名函数,这个匿名函数又引用了函数外的变量n,因此匿名函数+n组成了一个整体,形成闭包
当调用f函数时,n仅仅被初始化一次,因此每次调用形成累计 */ func main() {
//调用addUpper函数,获取返回值
f := test()
//此时f是匿名函数,对其传参调用
fmt.Println(f(50)) //10+50=60
fmt.Println(f(20)) //60+20=80
fmt.Println(f(20)) //80+20=100 同一个f对象,保留了n的值 //新的初始化
f1 := test()
fmt.Println(f1(10))
}
2. 闭包实战
package main import (
"fmt"
"strings"
) /*
1.makeSuffixFunc函数接收一个文件名后缀,如.png,且返回闭包
2.调用闭包,传入文件名前缀,如果没有后缀就添加后缀,返回 文件名.png
3.strings.HasSuffix可以判断指定字符串后缀
*/ func makeSuffixFunc(suffix string) func(string) string {
//返回值闭包函数
return func(filename string) string {
//如果没有xx后缀,执行代码
if !strings.HasSuffix(filename, suffix) {
//则字符串拼接
return filename + suffix
}
//否则有后缀名,则直接返回新文件名
return filename
}
} func main() {
//f1返回的是闭包函数,对此闭包函数进行功能性使用
f1 := makeSuffixFunc(".png") fmt.Println(f1("苍老师")) //没有后缀
fmt.Println("小泽老师.png") //有后缀
}
总结:
1.makeSuffixFunc函数中的变量suffix和返回值匿名函数,组合成了一个闭包
2.由于闭包函数保留了上次引用的值suffix,只需要传入一次,即可反复使用
2.1. 函数式编程
支持将函数作为另一个函数的参数,叫回调函数。
支持将函数作为另一个函数的返回值。
package main import "fmt" //闭包函数
//函数体内有局部变量 func adder() func(int) int {
sum := 0
//return 的是一个闭包
return func(v int) int {
//引用自由变量,sum
sum += v
return sum
}
} //递归定义
type iAdder func(int) (int, iAdder) //函数式编程写法,函数+常量
func adder2(base int) iAdder {
return func(v int) (int, iAdder) {
return base + v, adder2(base + v)
}
} func main() {
// a := adder() is trivial and also works.
a := adder2(0)
for i := 0; i < 10; i++ {
var s int
s, a = a(i)
fmt.Printf("0 + 1 + ... + %d = %d\n",
i, s)
}
}
go闭包-斐波那契数列
package main import "fmt" // 1,1,2,3,5,8,13,21,34,55...
//
func fibonacci() func() int {
a, b := 0, 1
return func() int {
a, b = b, a+b
return a
} } func main() {
f := fibonacci()
//斐波那契数列
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f()) }
2.2. python中闭包
def adder():
sum = 0
def f(value):
nonlocal sum
sum +=value
return sum
return f
5.4 Go 闭包的更多相关文章
- 《Web 前端面试指南》1、JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
- 干货分享:让你分分钟学会 JS 闭包
闭包,是 Javascript 比较重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,很难从定义去理解它.因此,本文不会对闭包的概念进行大篇幅描述 ...
- 深入浅出JavaScript之闭包(Closure)
闭包(closure)是掌握Javascript从人门到深入一个非常重要的门槛,它是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现.下面写下我的学习笔记~ 闭包-无处不 ...
- javascript之闭包理解以及应用场景
半个月没写博文了,最近一直在弄小程序,感觉也没啥好写的. 之前读了js权威指南,也写了篇博文,但是实话实说当初看闭包确实还是一头雾水.现在时隔一个多月(当然这一段时间还是一直有在看闭包的相关知识)理解 ...
- js闭包 和 prototype
function test(){ var p=200; function q(){ return p++; } return q; } var s = test(); alert(s()); aler ...
- js闭包for循环总是只执行最后一个值得解决方法
<style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...
- JavaScript学习笔记(二)——闭包、IIFE、apply、函数与对象
一.闭包(Closure) 1.1.闭包相关的问题 请在页面中放10个div,每个div中放入字母a-j,当点击每一个div时显示索引号,如第1个div显示0,第10个显示9:方法:找到所有的div, ...
- 带你一分钟理解闭包--js面向对象编程
上一篇<简单粗暴地理解js原型链--js面向对象编程>没想到能攒到这么多赞,实属意外.分享是个好事情,尤其是分享自己的学习感悟.所以网上关于原型链.闭包.作用域等文章多如牛毛,很多文章写得 ...
- 如何设计一门语言(七)——闭包、lambda和interface
人们都很喜欢讨论闭包这个概念.其实这个概念对于写代码来讲一点用都没有,写代码只需要掌握好lambda表达式和class+interface的语义就行了.基本上只有在写编译器和虚拟机的时候才需要管什么是 ...
- JavaScript 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- 浅谈 PHP 与手机 APP 开发
来源:http://www.thinkphp.cn/topic/5023.html 一.先简单回答两个问题: 1.PHP 可以开发客户端?答:不可以,因为PHP是脚本语言,是负责完成 B/S架构 或 ...
- python学习22之函数式编程
'''''''''1.高阶函数:将函数作为参数传递到另一个函数中,作为这个函数的参数,这样的方式叫高阶函数(1)map:两个参数,一个是函数,一个是iterator,将函数依次作用于Iterator中 ...
- Kubernetes 命令行工具之kubctl
目录 1.何为kubectl 2.Kubectl基本使用 2.1.命令补全 2.2.快速查找资源 2.3.使用自定义输出格式 3.陈述式管理资源 3.1.管理namespace资源 3.2.管理Dep ...
- numpy库的学习笔记
一.ndarray 1.numpy 库处理的最基础数据类型是由同种元素构成的多维数组(ndarray),简称“数组”. 2.ndarray是一个多维数组的对象,ndarray数组一般要求所有元素类型相 ...
- 突然地心血来潮,为 MaixPy( k210 micropython ) 添加看门狗(WDT) C 模块的开发过程记录,给后来的人做开发参考。
事情是前几天群里有人说做个看门狗不难吧,5分钟的事情,然后我就怼了几句,后来才发现,原来真的没有看门狗模块鸭. 那好吧,那我就写一下好了,今天是(2020年4月30日)想着最后一天了,不如做点什么有价 ...
- CF1285 --- Dr. Evil Underscores
CF1285 --- Dr. Evil Underscores 题干 Today as a friendship gift, Bakry gave Badawy \(n\) integers \(a_ ...
- 【Linux常见命令】dos2unix命令,unix2dos命令
我们都知道.打回车键就是换行的意思. 在不同系统下打回车键效果是不同的: MAC OS下:dakdhih \r LINUX下:dakdhih \n DOS\WINDOWS下:dakdhih \r\n ...
- GitHub 被指审查内容,著名“换脸”开源项目 deepfake 遭限制访问
开发四年只会写业务代码,分布式高并发都不会还做程序员? >>> 昨天 Hacker News 上一条关于 deepfake 开源项目的帖子(https://news.ycombi ...
- 数学--数论--整除分块(巨TM详细,学不会,你来打我)
1.概念 从一道例题说起 在介绍整除分块之前,我们先来看一道算数题:已知正整数n,求∑i=1n⌊ni⌋已知正整数n,求∑i=1n⌊ni⌋在介绍整除分块之前,我们先来看一道算数题: 已知正整数n,求∑i ...
- vue2.0那些坑之使用elementUI后v-on:click事件不生效问题
最近在维护vue2.0的项目,遇到了不少坑,在这里说下引用elementui之后,使用v-on:click绑定点击事件无效的情况,如下图: 我想阻止冒泡事件,发现无效.这里将@click换成了@cli ...