Go xmas2020 学习笔记 09、Closures
课程地址 go-class-slides/xmas-2020 at trunk · matt4biz/go-class-slides (github.com)
主讲老师 Matt Holiday

09-Closures

变量的生命周期可以超过变量声明上下文的范围


左侧 f 只是函数指针,右侧 f 则是闭包。

Slice 需要一个特定的闭包签名函数。在闭包的上下文中,我唯一传递给我的闭包是 i、j 他们是整数,ss 也是这个函数的一部分虽然没有被明确传入。
package main
import "fmt"
func do(d func()) {
d()
}
func main() {
for i := 0; i < 4; i++ {
v := func() {
fmt.Printf("%d @ %p\n", i, &i)
}
do(v)
}
}
0 @ 0xc000016088
1 @ 0xc000016088
2 @ 0xc000016088
3 @ 0xc000016088
package main
import "fmt"
func main() {
s := make([]func(), 4)
for i := 0; i < 4; i++ {
s[i] = func() {
fmt.Printf("%d @ %p\n", i, &i)
}
}
for i := 0; i < 4; i++ {
s[i]()
}
}
4 @ 0xc000016088
4 @ 0xc000016088
4 @ 0xc000016088
4 @ 0xc000016088
当封闭 i 变量时,每个闭包需要一个引用。四个匿名函数引用的都是同一个 i ,在第一个循环退出后,i 值为 4。i 并没有被垃圾回收,因为它仍被 4 个匿名闭包函数所引用。每次打印都是 4
比如传入一个闭包函数作为回调函数的时候,所引用的值在回调执行前会发生改变,那会出现大问题。
在第一个循环内创建一个新变量,每次循环声明初始化一个新变量,每个闭包函数会引用这个新变量,每个 i2 地址不一样。
for i := 0; i < 4; i++ {
i2 := i // closure capture
s[i] = func() {
fmt.Printf("%d @ %p\n", i, &i)
}
闭包是一种函数,调用具有来自函数外部的附加数据。例如数据来自另一个函数的范围,并且它通过引用封闭(封盖)。被封闭参数有点像参数,但它并不是,它允许我们函数使用那些不能用参数传递的额外数据,例如有些被其他类型固定的数据而无法被传递的数据。我们需要注意 gotcha ,因为闭包通过引用封闭,如果闭包是异步执行的,那么我封闭(封盖)的变量可能会发生改变。正如前面的例子,修复方法就是创建一个对应的本地副本,让闭包函数关闭(封盖)本地副本,这样副本的值就固定了。
Go xmas2020 学习笔记 09、Closures的更多相关文章
- 机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据
机器学习实战(Machine Learning in Action)学习笔记————09.利用PCA简化数据 关键字:PCA.主成分分析.降维作者:米仓山下时间:2018-11-15机器学习实战(Ma ...
- C++ GUI Qt4学习笔记09
C++ GUI Qt4学习笔记09 qtc++ 本章介绍Qt中的拖放 拖放是一个应用程序内或者多个应用程序之间传递信息的一种直观的现代操作方式.除了剪贴板提供支持外,通常它还提供数据移动和复制的功 ...
- CSS学习笔记09 简单理解BFC
引子 在讲BFC之前,先来看看一个例子 <!DOCTYPE html> <html lang="en"> <head> <meta cha ...
- [原创]java WEB学习笔记09:ServletResponse & HttpServletResponse
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Go xmas2020 学习笔记 11、io.Reader
11-Homework #2. 11-Reader. Reader interface. NewReader func. Reader Struct. Len .Size,Read func. Pra ...
- AMQ学习笔记 - 09. Spring-JmsTemplate之接收
概要 JmsTemplate提供了4组*3,共计12个接收用的方法. JmsTemplate接收所需要的资源ConnectionFactory和Destination,和发送是一致的. 接收的 ...
- Go xmas2020 学习笔记 12、Structs, Struct tags & JSON
12-Structs, Struct tags & JSON. Struct. Struct Gotcha. Anonymous Struct Type. Make the zero valu ...
- Go xmas2020 学习笔记 10、Slices in Detail
10-Slices in Detail. Slice. Empty vs nil slice
- Go xmas2020 学习笔记 07、Formatted & File I/O
07-Formatted & File I/O. I/O steams. formatted I/O. fmt functions. file I/O. Practice ① I/O. Alw ...
随机推荐
- interrupt(),interrupted() 和 isInterrupted() 的区别
1. 结论先行 interrupt():将调用该方法的对象所表示的线程标记一个停止标记,并不是真的停止该线程. interrupted():获取当前线程的中断状态,并且会清除线程的状态标记.是一个是静 ...
- Makefile 入门(加减乘除实现)
Makefile 入门(加减乘除实现) 准备 使用任意Linux发行版即可,本文使用WSL Ubuntu. 开始之前,需要安装必要的工具: sudo apt install make g++ 开始 1 ...
- 使用.Net6中的System.Text.Json遇到几个常见问题及解决方案
前言 以前.NetCore是不内置JSON库的,所以大家都用Newtonsoft的JSON库,而且也确实挺好用的,不过既然官方出了标准库,那更方便更值得我们多用用,至少不用每次都nuget安装Newt ...
- CSV格式的文件与EXCEL文件的区别
CSV格式的文件与EXCEL文件的区别 Excel CSV 这是一个二进制文件,它保存有关工作簿中所有工作表的信息 CSV代表Comma Separated Values .这是一个纯文本格式,用逗号 ...
- VS2022 安装.NET 3.5/.NET 4/.NET 4.5/.NET 4.5.1目标包的方法
最近重装了系统,就装了一个Visual Studio 2022,发现之前的老项目打不开了,需要下载目标包,但是在Visual Studio Installer 里面无法安装 .NET 3.5/.NET ...
- c# / .net wFramework winform 之运行后的窗体窗口可拖动操作
学习winform 的同志们可能会有这样的提问,我运行起来的窗体或者窗口该如何实现可拖动呢?今天它来了 思路:可以给窗体增加一个进度条(progressBar控件) 全局定义这几个变量: long p ...
- 修复ST-LINK V2下载器 | ST-LINK V2下载器烧录DAPLink固件
前言 某宝上的STLINK V2下载器偶尔会坏掉,我们尝试修复一下 1.材料 (1)完好的STLINK V2下载器和坏掉的下载器各1个: (2)固件:https://gitee.com/Cai-Zi/ ...
- luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分)
luoguP4383 [八省联考2018]林克卡特树(树上dp,wqs二分) Luogu 题解时间 $ k $ 条边权为 $ 0 $ 的边. 是的,边权为零. 转化成选正好 $ k+1 $ 条链. $ ...
- webdriver原理及操作
webdriver原理: 1. WebDriver 启动目标浏览器,并绑定到指定端口.该启动的浏览器实例,做为 webdriver 的 remote server. 2. Client 端通过 Com ...
- 面试问题之计算机网络:OSI七层网络模型及相关协议
一.应用层 功能:为应用程序提供服务并规定应用程序中通信相关的细节: 包括的协议如下: 1.超文本传输协议HTTP:这是一种基本的客户机/服务器的访问协议:浏览器向服务器发送请求,而服务器会应相应的网 ...