go特性-defer
1:后定义的defer先执行(可以理解为栈的方式)
// 222
// 111
func Test1(t *testing.T) {
defer fmt.Println("111")
defer fmt.Println("222")
}
2:defer定义的函数的参数,在定义的时候已经被赋值了
// defer 函数定义的时候,参数已经被赋值了(参数被捕捉了)
// 输出:
// 第二个defer: 2
// 第一个defer: 1
func Test2(t *testing.T) {
a := 1
// 注意这里,a作为defer函数的参数。defer函数定义的时候,就把a的值确定了
defer fmt.Println("第一个defer: ", a)
defer func() {
fmt.Println("第二个defer: ", a)
}()
a+=1
}
3:defer函数可以修改具名返回值,但不会修改匿名返回值
/////////////////////////////////////////////////////////
// defer 函数可以修改具名返回值,但是不会修改匿名返回值
// 输出
// fHasName: 2
// fNoName: 1
func fHasName() (val int) {
val = 1
defer func() {
// 因为val是个具名返回值,所以这里对val的操作,会影响到返回值
val += 1
}()
return val
}
func fNoName() int {
val := 1
defer func() {
// 这里的操作则不会影响返回值
val += 1
}()
return val
}
4:遇到panic的时候,当前协程调用栈已定义的defer将被执行,如果当前协程没有任何一个defer函数内执行了recover,那么执行完所有的defer之后,将会触发panic退出进程
/* 输出
has: 333
err: haha
has: 222
has: 111
*/
func TestHasRecover(t *testing.T) {
defer fmt.Println("has: 111")
defer fmt.Println("has: 222")
defer func() {
if err := recover(); err != nil {
fmt.Println("err:", err)
}
}()
defer fmt.Println("has: 333")
panic("haha")
defer fmt.Println("has: 444")
}
/* 输出
has: 333
has: 222
has: 111
panic: haha [recovered]
panic: haha
goroutine 19 [running]:
testing.tRunner.func1.1(0x95df20, 0x9b2110)
C:/Go/src/testing/testing.go:1076 +0x310
testing.tRunner.func1(0xc000140480)
C:/Go/src/testing/testing.go:1079 +0x43a
*/
func TestNoRecover(t *testing.T) {
defer fmt.Println("has: 111")
defer fmt.Println("has: 222")
defer fmt.Println("has: 333")
panic("haha")
defer fmt.Println("has: 444")
}
最后来一道总结题,如下代码会输出什么?
import "testing"
import "fmt"
func sum(tip string, a int, b int) int {
sum := a + b
fmt.Printf("tip=%s a=%d b=%d sum=%d\n", tip, a, b, sum)
return sum
}
func deferSum() {
a := 1
b := 2
defer sum("1tip", a, sum("2tip", a, b))
a = 3
defer func(b int) {
sum("3tip", a, sum("4tip", a, b))
}(a)
b = 4
defer func() {
sum("5tip", a, sum("6tip", a, b))
}()
}
func TestDeferSum(t *testing.T) {
deferSum()
}
正确答案如下:
tip=6tip a=3 b=4 sum=7
tip=5tip a=3 b=7 sum=10
tip=4tip a=3 b=3 sum=6
tip=3tip a=3 b=6 sum=9
tip=1tip a=1 b=3 sum=4
go特性-defer的更多相关文章
- golang学习 ---defer语句
golang语言defer特性详解 defer语句是go语言提供的一种用于注册延迟调用的机制,它可以让函数在当前函数执行完毕后执行,是go语言中一种很有用的特性.由于它使用起来简单又方便,所以深得go ...
- Python也可以拥有延迟函数
延迟函数defer 我们知道在Golang中有一个关键字defer,用它来声明在函数调用前,会让函数*延迟**到外部函数退出时再执行,注意,这里的退出含义:函数return返回或者函数panic退出 ...
- 浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
defer和async特性相信是很多JavaScript开发者"熟悉而又不熟悉"的两个特性,从字面上来看,二者的功能很好理解,分别是"延迟脚本"和"异 ...
- Go defer 特性和使用场景
golang 的 defer 语句用于延迟调用.defer 会在当前函数返回之前执行 defer 注册的函数.比如 defer func_defer() 这样语句会让你注册一个函数变量到 defer ...
- JS魔法堂:ES6新特性——GeneratorFunction介绍
一.前言 第一次看koajs的示例时,发现该语句 function *(next){...............} ,这是啥啊?于是搜索一下,原来这是就是ES6的新特性Generator ...
- 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)
这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...
- iOS - Swift Swift 语言新特性
1.Swift 2.0 带来哪些新变化 常规变化: 1.OS X 10.11.iOS 9 和 watchOS 2 SDK 采纳了一些 Objective-C 的特性用来提高 Swift 的编程体验, ...
- HTML5 <script>元素async,defer异步加载
原文地址:HTML5′s async Script Attribute原文日期: 2010年09月22日翻译日期: 2013年08月22日 (译者注: 异步加载,可以理解为无阻塞并发处理.) (译者再 ...
- javascript笔记——js的阻塞特性[转载]
JS具有阻塞特性,当浏览器在执行js代码时,不能同时做其它事情,即<script>每次出现都会让页面等待脚本的解析和执行(不论JS是内嵌的还是外链的),JS代码执行完成后,才继续渲染页面. ...
随机推荐
- 仅用六种字符来完成Hello World,你能做到吗?
Hello World 对于每一个开发者来说都不陌生,因为在我们学习任何一个语言或框架的时候,都会有一个Hello World的案例来帮助我们快速入门. 如果我们使用JavaScript来输出Hell ...
- input 与 button 的问题 (空隙/不等高/对不齐)及 解决办法
1. input 与 button 为什么有空隙? - 要明白为什么,需要了解一下几点基础知识(耐心看完,你会发现竟如此简单) 1. input 与 button 都属于行级块元素,都具有文本 ...
- 用DOM和DOM4J写xml文件时,怎样设置xml文档的编码
//在将xml文档传输出去时,利用Transformer中的setOutputProperty方法 TransformerFactory trans = TransformerFactory.newI ...
- 利用Servlet做一套增删改查
真的,稳住,考上研,利用两年逆袭.一步一步来,实在不行,最后最差也不过就是就回家种地,想想也不错. 前期准备配置 建一个动态web项目 新建Dynamic Web ProjectFile->Ne ...
- Linux系统下用户如何膝盖FTP用户密码
其实修改ftp用户密码与修改普通用户的密码的过程是一眼高的其具体步骤如下 1.用root账户登录系统 2.使用passwd命令修改密码: 第一次输入密码后提示:The password fails t ...
- 周末我把HashMap源码又过了一遍
为什么在Java面试中总是会问HashMap? HashMap一直是Java面试官喜欢考察的题目,无论应聘者你处于哪个级别,在多轮的技术面试中似乎总有一次会被问到有关 HashMap 的问题. 为什么 ...
- c语言 :write与read系统调用总结
在学习的时候总是有点迷糊于是在网上找到一些比较好的分享一下 下面举一个例子: 1 #include <stdio.h> 2 #include <unistd.h> 3 #in ...
- tcpdump详解(转)
tcpdump是Linux下强大的抓包工具,不仅可以分析数据包流向,还可以对数据包内容进行监听.通过分析数据包流向,可以了解一条连接是如何建立双向连接的.tcpdump允许用户(一般是root)拦截和 ...
- Python生成csv中文乱码解决办法
前言 在Linux下面用python进行数据处理,然后输出为csv格式,如果没有中文一切正常,但是如果有中文,就会出现乱码的问题,本篇将讲述怎么处理这个问题 处理过程 原始代码 #!/usr/bin/ ...
- 手把手教你5分钟从零开发一款简易的IDEA插件!项目经验/毕设不愁了!
我这个人没事就喜欢推荐一些好用的 IDEA 插件给大家.这些插件极大程度上提高了我们的生产效率以及编码舒适度. 不知道大家有没有想过自己开发一款 IDEA 插件呢? 我自己想过,但是没去尝试过.刚好有 ...