疑惑return后面的defer到底会不会执行?

taatcc · 2019-08-28 16:43:36 · 4572 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2019-08-28 16:43:36 的主题,其中的信息可能已经有所发展或是发生改变。

package main

import (
    "fmt"
)

var a bool = true
func main() {
    defer func(){
        fmt.Println("err1:")
    }()
    if a == true {
        fmt.Println("is true")
        return
    }
    defer func(){
        fmt.Println("err2:")
    }()
}

输出:

is true
err1:
可见,return后面的defer没执行
在该网站看到一篇文章,说defer任何时候都会执行,如下:

https://studygolang.com/articles/22646

func CopyFile(dstName, srcName string) (written int64, err error) {
    src, err := os.Open(srcName)
    if err != nil {
        return
    }
    defer src.Close()
    dst, err := os.Create(dstName)
    if err != nil {
        return
    }
    defer dst.Close()
    return io.Copy(dst, src)
}
src 和 dst 都能及时清理和释放,无论 return 在什么地方执行。

请问如果return后,defer src.Close()真的会执行吗?


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4572 次点击  ∙  2 赞  
加入收藏 微博
10 回复  |  直到 2019-09-07 11:42:19
jdxj
jdxj · #1 · 6年之前

需要先让 defer 语句执行, 之后才能在 return 之前执行 defer 关键字后的函数 (或方法). 原理

taatcc
taatcc · #2 · 6年之前
jdxjjdxj #1 回复

需要先让 `defer` 语句执行, 之后才能在 `return` 之前执行 `defer` 关键字后的函数 (或方法). [原理](https://draveness.me/golang/keyword/golang-defer.html)

我也觉得,return之前的defer才会执行,return后面的defer是不会执行的

qqa64
qqa64 · #3 · 6年之前

不会,defer要写在前面

skyfile
skyfile · #4 · 6年之前

defer 要先执行注册,return 后会按先进后出的顺序去调用已注册的defer方法

taatcc
taatcc · #5 · 6年之前

有了defer,看代码的时候也要先读异常处理代码,再看panic,一般来说应该是写panic(throw),再写异常处理</br> go真是特立独行啊!!!

fwhez
fwhez · #6 · 6年之前

defer的含义是,入栈 return后面的话,还没入,就return了

popstk
popstk · #7 · 6年之前

不会,文章代码dst, err := os.Create(dstName) ,err != nil 时,dst是nil,根本不需要清理,后面的defer dst.Close()也不会执行,表达的是一个意思,没有矛盾。

taatcc
taatcc · #8 · 6年之前
popstkpopstk #7 回复

不会,文章代码`dst, err := os.Create(dstName)` ,err != nil 时,dst是nil,根本不需要清理,后面的`defer dst.Close()`也不会执行,表达的是一个意思,没有矛盾。

原来是这个意思。这样的话,确实符合逻辑

cyboy
cyboy · #9 · 6年之前

image.png ??? 没有这样的操作

tylitianrui
tylitianrui · #10 · 6年之前

你说的这不是defer机制问题,你这只是语法的问题。defer首先是压栈,带到panic或者return等时,会pop出来执行。你这个例子if err != nil { return } 直接return了 defer不会执行

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传