64

defer 的一些用法和猜测

 5 years ago
source link: https://www.tuicool.com/articles/bAvmYf3
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

以前的代码中,基本上只使用了 defer 作为防御程序 panic 退出的手段,没有仔细考虑过对返回值的影响。今天有同事提到:

如果执行过程中发生 panic,defer函数 recover() != nil 的情况下,未命名的返回值的函数会返回什么呢?

之前并没有没有想过这个问题,猜想应该是返回该类型的默认值,试了一下果然如此。

func fooA() float64 {
    defer func() {
        if err := recover(); err != nil {
        }
    }()

    *(*float64)(nil) = 0.1 // panic
    return 1.0
}

fooA() 返回0。

那么如果 defer 函数返回值和上层函数一致,会不会替换掉返回值呢?(

会就有鬼了

)

func fooB() float64 {
    defer func() float64 {
        if err := recover(); err != nil {
            return 1.1
        } else {
            return 1.2
        }
    }()

    *(*float64)(nil) = 0.1
    return 1.0
}

fooB() 返回0。

事实上,如果要在 defer 中修改函数的返回值,目前我只知道一种办法:使用命名的返回参数:

func fooC() (x float64) {
    defer func() {
        if err := recover(); err != nil {
            x = 1.1
            return
        }
    }()

    *(*float64)(nil) = 0.1
    return 1.0
}

fooC() 返回1.1。

官方文档上面的说明:

https://golang.org/ref/spec#Defer_statements

核心的说明我认为是这一句话:

That is, if the surrounding function returns through an explicit return statement , deferred functions are executed  after any result parameters are set by that return statement but  before the function returns to its caller.

搜索信息的过程中发现这样的一篇文章: 一道考察defer与命名返回值的题目

DeferFunc1 和 DeferFunc3 还比较好解释,对于文中的DeferFunc2,强行猜测了一下:

func dfB(i int) int { // return anonymous int,we assume it named `noNameI`。
    t := i // Local var t is assigned to 1.
    defer func() {
        // Here noNameI is 2, t is 1.
        t += i // t is 3, noNameI unchanged.
    }()
    return 2 // noNameI is assigned to 2.
}

dfB() 返回 2,为什么呢?

代码 return 2 的时候应该是将2赋值给了匿名的返回值变量,因此 defer 函数中的对本地变量的 t 的操作便无关紧要。


Recommend

  • 68
    • www.jisilu.cn 7 years ago
    • Cache

    周一开盘的N种猜测

    周一开盘的N种猜测 - 周末的火药味道直接影响我天朝股民的钱包那么下周一的走势大佬们有何见解呀目前处于周末发起袭击者也已经宣告打击任务完成那么?周一A股会低开高走吗?如果俄罗斯强势回击要不要在腥风血雨中清仓股票呢

  • 45

    投中网(https://www.chinaventure.com.cn) 编者按:ofo这条商业化尝试的路,看起来道远且阻。 “生存或毁灭,这是个问题。” 莎翁笔下困扰着哈姆雷特的这个抉择,将换一种方式呈现在戴威面前:“独立还是投诚,这...

  • 58
    • studygolang.com 6 years ago
    • Cache

    Go语言中defer的一些坑

    defer语句是Go中一个非常有用的特性,可以将一个方法延迟到包裹该方法的方法返回时执行,在实际应用中,defer语句可以充当其他语言中try…catch…的角色,也可以用来处理关闭文件句柄等收尾操作。 defer触发时机 A "d...

  • 68
    • video.weibo.com 6 years ago
    • Cache

    永远不要去猜测你队友的性别

    永远不要去猜测你队友的性别

  • 57

    央广网上海10月3日消息(记者杨博宇)据中国之声《新闻晚高峰》报道,国庆长假期间,不少人都会选择出国购物旅游。这两天不少人的微信朋友圈都在转发这样一则消息:近日上海浦东机场正在严查海外购物进境,所有人全部开箱排队等待过机审查,仅一个航班抓了

  • 41

    新浪科技讯北京时间5月17日消息,据宇宙杂志网站报道,目前,研究人员表示,外星人可能使用引力波进行通讯,干涉仪参数的微小变化可能表明地球并不孤单,宇宙中或许存在着其他高智慧生命形式。一支物理学家小组建议,只需进行技术方面的稍微调整,欧洲航天

  • 47

  • 10

    Zcash副总裁回应Bittrex将下架Zcash:有太多猜测和错误信息  •  12 小时前 针对B...

  • 4

    defer, panic和recover用法【Golang 入门系列十四】 mb5fe94b3e552d9 · 大约10小时之前 · 23 次点击 · 预计阅读时间 3 分钟 · 不到1分钟之前 开始浏览    ...

  • 1
    • www.tuoluocaijing.cn 3 years ago
    • Cache

    关于蚂蚁链 NFT 业务的一些猜测

    关于蚂蚁链 NFT 业务的一些猜测 区块观察 2021-06-25 03:19 热度 262219 分享 微信扫一扫:分享 ...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK