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 闭包深入浅出
闭包是什么? 闭包是内部函数可以访问外部函数的变量.它可以访问三个作用域:首先可以访问自己的作用域(也就是定义在大括号内的变量),它也能访问外部函数的变量,和它能访问全局变量. 内部函数不仅可以访问外 ...
随机推荐
- beego rel/reverse
用户可以发布多个文章 对用户来说是一对多 对文章来说是多对一 用户是主表 文章是用户的从表 rel用在从表中,给主表结构体设置主键,也就是文章表对应用户表的外键 reverse用在主表中,指定主表与从 ...
- php里的闭包函数
一个匿名函数内要获取外部的变量必须要使用use: $message = 'hello'; $example = function() use ($message){ var_dump($message ...
- QIntValidator没有最小值的限制,继承然后写个新类来控制最小值
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/firecityplans/article ...
- Python 基础教程(第二版)笔记 (2) 字典
P59 字典方法 1. clear 2. copy, deepcopy 3. fromkeys 4. get 比下标安全 5. has_key 6. items, iteritems 7. keys, ...
- 牛客网练习赛61 A+B
A.打怪 思路:先判定当小怪的攻击力为0时,你能杀无数只怪,因为小怪A不动你,然后再计算每个小怪最多能给你造成多少伤害(用小怪的血量除以你的攻击力,也就是你砍它几下它会死,你先手,所以小怪肯定比你少砍 ...
- java 8 stream中的Spliterator简介
目录 简介 tryAdvance trySplit estimateSize characteristics 举个例子 总结 java 8 stream中的Spliterator简介 简介 Split ...
- 修改mysql配置中my.conf中max_allowed_packet变量
mysql根据配置文件会限制server接受的数据包大小. 有时候大的插入和更新会受max_allowed_packet 参数限制,导致写入或者更新失败. 查看目前配置 show VARIABLES ...
- 01-复杂度2 Maximum Subsequence Sum
01-复杂度2 Maximum Subsequence Sum (25分) 时间限制:200ms 内存限制:64MB 代码长度限制:16kB 判题程序:系统默认 作者:陈越 单位:浙江大学 htt ...
- Fourier Transform
为了在统一框架里分析周期信号与非周期信号,可以给周期信号也建立傅里叶变换. 有两种方法求周期信号的傅里叶变换: **1. 利用傅里叶级数进行构造 ** 对于周期信号\(x(t)\),其傅里叶级数展开式 ...
- HDU Problem D [ Humble number ]——基础DP丑数序列
Problem D Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submi ...