教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 go那些事儿|defer必掌握知识

go那些事儿|defer必掌握知识

发布时间:2022-03-05   编辑:jiaochengji.com
教程集为您提供go那些事儿|defer必掌握知识等资源,欢迎您收藏本站,我们将为您提供最新的go那些事儿|defer必掌握知识资源
<blockquote>

目录

</blockquote><ul><li>defer执行时机</li><li>defer执行顺序</li><li>defer与return谁先谁后</li><li>函数包含多个Panic,defer中recover处理那个Panic</li><li>函数返回值遇到defer</li><li>defer遇到Panic<ul style="list-style-type:square;"><li>defer遇到Panic,但是并不捕获异常的情况</li><li>defer遇到Panic,并捕获异常</li></ul></li><li>练习:defer面试题</li><li>闲聊</li><li>欢迎加入我的公众号【迈莫coding】 一起pk大厂</li></ul><h1>defer执行时机</h1><ul><li>return 语句执行完之后,如果有 defer 语句,再执行 defer 语句</li><li>发生 Panic ,也会触发 defer 执行</li></ul><h1>defer执行顺序</h1><blockquote>

多个defer出现时,会以"先进后出,后进先出"的规则来执行,类似于数据结构中栈的执行顺序.

</blockquote>

示例:

<pre>package main  import "fmt"func main() {  defer func(){     fmt.Println("A")   }()  defer func(){     fmt.Println("B")   }  defer func(){     fmt.Println("C")   } }复制代码</pre>

结果:

<pre>C B A复制代码</pre><h1>defer与return谁先谁后</h1>

示例代码

<pre>package main  import "fmt"func deferFunc() {   fmt.Println("defer func") }func returnFunc() int {   fmt.Println("return func")  return 1}func returnAndDefer() int {  defer deferFunc()  return returnFunc() }func main() {   returnAndDefer() }复制代码</pre>

结果

<pre>return funcdefer func复制代码</pre>

结论

<pre>一个函数中即有return语句,也有defer语句,先执行return语句,后执行defer语句复制代码</pre><h1>函数包含多个Panic,defer中recover处理那个Panic</h1>

示例

<pre>package mainimport "fmt"func main() {  defer func() {if err := recover(); err != nil {       fmt.Println(err)     }else {       fmt.Println("fail")     }   }()  defer func() {panic("defer panic")   }()  panic("main panic") }复制代码</pre>

结果

<pre>defer panic复制代码</pre>

结论

<pre>只有最后一个panic,可以被recover捕获到.复制代码</pre><h1>函数返回值遇到defer</h1>

示例

<pre>package mainimport "fmt"func deferFunc() (t int) { // t初始化为0,并且作用域为该函数全域   defer func() {     t = t * 10   }()  return 1}func main() {   fmt.Println(deferFunc()) }复制代码</pre>

结果

<pre>10 复制代码</pre>

结论

<pre>当调用deferFunc()函数时,本应该返回值1,但函数中还有defer语句, 所以在return语句之后,又被defer的匿名函数func函数执行,所以t=t*10被执行。因此返回值为10.复制代码</pre><h1>defer遇到Panic</h1><h2>defer遇到Panic,但是并不捕获异常的情况</h2>

示例

<pre>package mainimport "fmt"func defer_panic() {  defer func() {     fmt.Println("defer: panic() 执行1")   }()  defer func() {      fmt.Println("defer: panic() 执行2")   }  panic("发生异常")   fmt.Println("该条语句无法执行") }func main() {   defer_panic()   fmt.Println("main函数执行完成") }复制代码</pre>

结果

<pre>defer: panic() 执行2defer: panic() 执行1panic: 发生异常// 异常信息...复制代码</pre><h2>defer遇到Panic,但捕获异常的情况</h2>

示例

<pre>package mainimport "fmt"func defer_panic() {  defer func() {     fmt.Println("defer: panic() 执行1")if err := recover(); err != nil {       fmt.Println(err)     }   }()  defer func() {      fmt.Println("defer: panic() 执行2")   }  panic("发生异常")   fmt.Println("该条语句无法执行") }func main() {   defer_panic()   fmt.Println("main函数执行完成") }复制代码</pre>

结果

<pre>defer: panic() 执行2defer: panic() 执行1发生异常 main函数执行完成复制代码</pre><h1>练习:defer面试题</h1>

1. 下面代码输出什么?

<pre>package mainimport "fmt"func main() {   var name = "zhangsan"    fmt.Println(name)   defer fmt.Println(name)    name = "lisa"    fmt.Println(name)   defer fmt.Println(name) }复制代码</pre><blockquote>

考点

</blockquote><pre>defer和函数组合调⽤方式  复制代码</pre><blockquote>

结果

</blockquote><pre>zhangsan lisa lisa zhangsan  复制代码</pre>

2. 程序运行结果

<blockquote>

示例

</blockquote><pre>package mainimport (   "fmt")func main() {    defer_call() }func defer_call() {   defer func() { fmt.Println("迈") }()   defer func() { fmt.Println("莫") }()   defer func() { fmt.Println("coding") }() }复制代码</pre><blockquote>

考点

</blockquote><pre>defer和函数组合调⽤方式  复制代码</pre><blockquote>

结果

</blockquote><pre>coding 莫 迈复制代码</pre>

3. 下面代码输出什么?

<blockquote>

示例

</blockquote><pre>package mainimport "fmt"func DeferFunc1(i int) (t int) {     t = idefer func() {         t  = 3}()return t }func main() {     fmt.Println(DeferFunc1(1)) }复制代码</pre><blockquote>

考点

</blockquote><pre>defer和函数组合调⽤方式  复制代码</pre><blockquote>

结果

</blockquote><pre>4复制代码</pre><blockquote>

执行过程

</blockquote><pre>1. 将返回值t赋值为行参i,t = 12. 执行return语句,将t 赋值给t3. 执行defer语句,t   3 = 44. 返回值4复制代码</pre>

4. 下面代码输出什么?

<blockquote>

示例

</blockquote><pre>package mainimport "fmt"func DeferFunc2(i int) int {     t := idefer func() {         t  = 3}()return t }func main() {     fmt.Println(DeferFunc2(1)) }复制代码</pre><blockquote>

考点

</blockquote><pre>defer和函数组合调⽤方式  复制代码</pre><blockquote>

结果

</blockquote><pre>1复制代码</pre><blockquote>

执行过程

</blockquote><pre>1. 创建变量t并将其赋值为i的值,t = 12. 执行return语句,注意这里是将t赋值给返回值,此时返回值为1(这个返回值并不是t)3.执行defer语句,t = t   3 = 44. 函数返回值1复制代码</pre>

5. 下面代码输出什么?

<blockquote>

示例

</blockquote><pre>package mainimport "fmt"func DeferFunc3(i int) (t int) {defer func() {         t  = i     }()return 2}func main() {     fmt.Println(DeferFunc3(1)) }复制代码</pre><blockquote>

考点

</blockquote><pre>defer和函数组合调⽤方式  复制代码</pre><blockquote>

结果

</blockquote><pre>3复制代码</pre><blockquote>

执行过程

</blockquote><pre>1. 首先将t赋值为22. 执行defer语句,t = t   1 = 33. 函数返回值3复制代码</pre>

6. 下面代码输出什么?

<blockquote>

示例

</blockquote><pre>package mainimport "fmt"func DeferFunc4() (t int) {defer func(i int) {         fmt.Println(i)         fmt.Println(t)     }(t)     t = 1return 2}func main() {     DeferFunc4() }复制代码</pre><blockquote>

考点

</blockquote><pre>defer和函数组合调⽤方式  复制代码</pre><blockquote>

结果

</blockquote><pre>02复制代码</pre><blockquote>

执行过程

</blockquote><pre>1. 初始化返回值t为零值 02. 首先执行defer的第一步,赋值defer中的func入参t为03. 执行defer的第二步,将defer压栈4. 将t赋值为15. 执行return语句,将返回值t赋值为26. 执行defer的第三步,出栈并执行7. 因为在入栈时defer执行的func的入参已经赋值了,此时它作为的是一个形式参数,所以打印为0;8. 相对应的因为最后已经将t的值修改为2,所以再打印一个2复制代码</pre><h1>闲聊</h1><ul><li>读完文章,自己是不是和defer的cp率又提高了</li><li>我是迈莫,欢迎大家和我交流</li></ul><blockquote>

原创不易,觉得文章写得不错的小伙伴,点个赞???? 鼓励一下吧~

</blockquote><h1>
</h1>
到此这篇关于“go那些事儿|defer必掌握知识”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
go那些事儿|defer必掌握知识
defer ,panic,recover
快速掌握前端开发技巧
python数据分析师需要学什么
go 语言学习历程
photoshop基础图层与蒙版使用技巧心得
想系统学习GO语言(Golang
使用 defer 还是不使用 defer?
想学一门新的编程语言?考虑一下Go (Golang)吧
Golang Defer详解

[关闭]
~ ~