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 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- Blazor WebAssembly 3.2.0 正式起飞,blazor 适合你吗?
最近blazor更新很快,今天在官方博客上发布了Blazor WebAssembly 3.2.0 RC:https://devblogs.microsoft.com/aspnet/blazor-web ...
- css之颜色表示法
css之颜色表示法 十六进制颜色 所有浏览器都支持十六进制颜色值. 十六进制颜色是这样规定的:#RRGGBB,其中的 RR(红色).GG(绿色).BB(蓝色)十六进制整数规定了颜色的成分.所有值必须介 ...
- Xapian实战(四):搜索
参考资料: 学习Xapian(1)-基础的建索引和搜索 1. Xapian中用于搜索的类 Enquire - 提供了检索的接口:(Enquire API) QueryParser(QueryParse ...
- Clickhouse 时区转换(下)
Clickhouse 时区转换续—时区参数转换 天天加班,时间不够,主要还是我太懒,流汗,,,,,,另外如果这篇学习笔记超过100阅读量并有评论,我可能半夜也会爬起来更新的. 相信大家看我之前记录的这 ...
- Vue页面权限控制和动态添加路由
原文转自:点我 页面权限控制 页面权限控制是什么意思呢? 就是一个网站有不同的角色,比如管理员和普通用户,要求不同的角色能访问的页面是不一样的.如果一个页面,有角色越权访问,这时就得做出限制了. Vu ...
- CodeForces - 262B
Roma works in a company that sells TVs. Now he has to prepare a report for the last year. Roma has g ...
- 【K8S】K8S 1.18.2安装dashboard(基于kubernetes-dashboard 2.0.0版本)
[K8S]K8S 1.18.2安装dashboard(基于kubernetes-dashboard 2.0.0版本) 写在前面 K8S集群部署成功了,如何对集群进行可视化管理呢?别着急,接下来,我们一 ...
- thinkphp下的Webshell&&php过D盾一句话
环境: Thinkphp 5.0.15 PHP version:7.0.12 WAF: D盾 ,安全狗 Thinkphp 采用 MVC 模式 核心:模块 -> 控制器 –> 方法 思路: ...
- Java——深入理解Java异常体系
该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 前言: Java的基 ...
- JAVA设计模式之工厂系列(factory)
任何可以产生对象的方法或者类,都可以称之为工厂.单例就是所谓的静态工厂. 为什么jdk中有了new,还需要工厂呢? a.灵活的控制生产过程 b.给对象加修饰.或者给对象加访问权限,或者能够在对象生产过 ...