golang基础--细说defer
defer 匿名函数特性
执行方式类似其它语言中的析构函数,在函数体执行结束后按照调用顺序的
相反顺序逐个执行//执行顺序相反
package main
import "fmt" func main() {
fmt.Println("a")
defer fmt.Println("b")
defer fmt.Println("c")
}
/*输出
a
c
b
*/
即使函数发生
严重的错误也会执行,类似于try...except常用于 资源清理,文件关闭,解锁以及记录时间等操作
支持匿名函数的调用
通过于匿名函数配合可在return之后修改函数计算的结果
-如果函数体内某个变量作为defer时匿名函数的参数,则在定义defer时即已经获得了拷贝,否则 则时引用某个变量的地址//支持匿名函数
package main
import "fmt" func main() {
for i := 0; i < 3; i++ {
defer func() { //函数体内的变量传递到defer匿名函数
fmt.Println(i) //此时引用的时变量i的地址
}()
}
} /*输出
3
3
3
*/
Go没有异常机制,但有panic/recover模式来处理错误
Panic可以在任何地方引发
panic错误机制
//panic 错误机制,遇到panic语句后,后面不会再执行
package main
import "fmt"
func main() {
A()
B()
C()
} func A() {
fmt.Println("func a")
} func B() {
panic("Panic B")
}
func C() {
fmt.Println("func")
} /*输出
A()--> func a
B()---> panic: Panic B
---------------
goroutine 1 [running]:
main.B()
C() C:/Users/faily/Desktop/workspace/src/defer1.go:17 +0x40
main.main()
C:/Users/faily/Desktop/workspace/src/defer1.go:8 +0x2c
exit status 2
exit status 1
*/
defer,配合recover及匿名函数处理程序出现的严重错误(panic语句),调过程序错误,继续执行,类似于python语言中
try...except,finally语句.//defer,recover机制,处理panic引发的机制
package main
import "fmt" func main() {
A()
B()
C()
} func A() {
fmt.Println("func a")
}
func B() {
defer func() { //defer函数放在panic之前
if err := recover(); err != nil { //注册recover函数(判断是否触发panic错误),并判断
fmt.Println("Recover in B") //如果程序出现panic,并且err不为nil(真实存在)
}
}() //记住,defer的匿名函数大括号后要加上()
panic("Panic B") //跳过程序错误,继续后面的执行。 }
func C() {
fmt.Println("func C") } /*输出
A()--> func a
B()--> Recover in B
C()--> func C
*/
- defer,匿名函数,变量传递,数组array,for循环综合
> 运行以下代码,并分析输出结果
```go
package main
import "fmt"
func main() {
var fs = [4]func(){} //定义一个变量fs,类型为一个数组,数组元素的类型是匿名函数func
for i := 0; i < 4; i++ {
defer fmt.Println("defer i=", i) //defer,遵循的是先进后出,所以for循环,最后执行这一句,i作为变量,正常传递
defer func() { fmt.Println("defer closure i=", i) }() // i从外部传递进defer匿名函数中,作为变量而非匿名函数参数,此时引用的是i的内存地址(只会引用i的最后值)
fs[i] = func() { fmt.Println("closure i=", i) } //为fs数组索引赋值,i传递进匿名函数并没有作为参数,所以i引用的是i的内存地址(只会引用i的最后值)
fmt.Println(i)
}
for n, f := range fs { // for 循环数组,执行每一个元素(匿名函数)
fmt.Println(n)
f()
}
}
/*输出
n=0
closure i= 4
n=1
closure i= 4
n=2
closure i= 4
n=3
closure i= 4
------------------------
defer closure i= 4
defer i= 3
defer closure i= 4
defer i= 2
defer closure i= 4
defer i= 1
defer closure i= 4
defer i= 0
*/
```
分析结果,详见代码注释
golang基础--细说defer的更多相关文章
- 【Golang基础】defer执行顺序
defer 执行顺序类似栈的先入后出原则(FILO) 一个defer引发的小坑:打开文件,读取内容,删除文件 // 原始问题代码 func testFun(){ // 打开文件 file, ...
- Golang基础之函数
golang基础之函数 1.为什么需要函数? 有些相同的代码可能出现多次,如果不进行封装,那么多次写入到程序中,会造成程序冗余,并且可读性降低 2.什么是函数 为完成某些特定功能的程序指令集合称为函数 ...
- Golang 基础之基础语法梳理 (一)
大家好,今天将梳理出的 Go语言基础语法内容,分享给大家. 请多多指教,谢谢. 本次<Go语言基础语法内容>共分为三个章节,本文为第一章节 Golang 基础之基础语法梳理 (一) Gol ...
- Golang基础教程
以下使用goland的IDE演示,包含总计的golang基础功能共20个章节 一.go语言结构: 二.go基础语法: 三.变量 四.常量 五.运算符 六.条件语句 七.循环 八.函数 九.变量作用域 ...
- golang基础知识之encoding/json package
golang基础知识之json 简介 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式.可以去json.org 查看json标准的清晰定义.json pack ...
- GoLang基础数据类型--->字典(map)详解
GoLang基础数据类型--->字典(map)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 可能大家刚刚接触Golang的小伙伴都会跟我一样,这个map是干嘛的,是 ...
- GoLang基础数据类型-切片(slice)详解
GoLang基础数据类型-切片(slice)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数组的长度在定义之后无法再次修改:数组是值类型,每次传递都将产生一份副本.显然这种数 ...
- GoLang基础数据类型--->数组(array)详解
GoLang基础数据类型--->数组(array)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Golang数组简介 数组是Go语言编程中最常用的数据结构之一.顾名 ...
- GoLang基础数据类型--->字符串处理大全
GoLang基础数据类型--->字符串处理大全 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 欢迎加入: 高级运维工程师之路 59843264 ...
随机推荐
- 【TypeScript】TypeScript 学习 5——方法
在 JavaScript 中,有两种方式定义方法. 1.命名的方法 function add(x,y){ return x+y; } 2.匿名方法 var myAdd = function(x,y) ...
- CentOS7查看CPU个数
查看逻辑cpu个数:cat /proc/cpuinfo | grep "processor" | wc -l 查看物理cpu个数:cat /proc/cpuinfo | grep ...
- JS里关于特殊字符的转义
重定向的url里含有百分号“%”,遇到了apache 找不到该文件的报错.通过查询相关文档,知道了原来是url里含有特殊字符要转码才能定位到正确的地址.比如"%"要转码为" ...
- 自定义两个控件,一个是显示图标和文字的矩形,一个是带边框的label(但是不是label)
记录遇到的两个坑 坑1. 一开始我继承button 来实现下面的控件1,后面发现button没有双击事件.就改成继承UserControl了.重新编译,导致设计时的控件文本全部被清空,因为UserCo ...
- 爬虫Scrapy指令学习
1.新建一个新的爬虫项目指令 scrapy startproject xxx 2.在项目/spider目录下创建一个名为XXX的爬虫,并指定爬取域的范围 scrapy genspider XXX & ...
- 【CronExpression表达式详解和案例】(转载)
原文地址:https://www.cnblogs.com/pipi-changing/p/5697481.html 找了下Cron的资料,这篇作者写的比较清晰,转载记录一下,方便后面使用的时候在g ...
- day111 爬虫第一天
一.模拟浏览器发请求. import requests r1 =requests.get( url ="https://dig.chouti.com/", headers ={ & ...
- ASP.NET Core获取客户端IP地址
1.在ConfigureServices注入IHttpContextAccessor // ASP.NET Core 2.1的注入方式 //services.AddHttpContextAccesso ...
- Java基础学习篇---------多线程
一.编写两种多线程的方法 (1).Thread(它是继承Runnable的子类) class MyThread extends Thread{ private int ticket = 5; @Ove ...
- 650. 2 Keys Keyboard
Initially on a notepad only one character 'A' is present. You can perform two operations on this not ...