defer中拿不到返回值?

EddieChan1993 · 2018-07-10 10:49:33 · 1519 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2018-07-10 10:49:33 的主题,其中的信息可能已经有所发展或是发生改变。

err返回值没有获取到,求解答!

package main

import "fmt"

func main() {
    fmt.Println(Parse())
}

func Parse() error {
    var err error
    defer func() {
        //选择性的recover
        switch p := recover(); p {
        case nil:
        case "what":
            err = fmt.Errorf("internal error")
            fmt.Println(err)
        default:
            panic(p)

        }
    }()
    panic("what")
    return err
}

输出值:

internal error
<nil>

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

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

1519 次点击  
加入收藏 微博
8 回复  |  直到 2018-07-11 10:55:38
sunanxiang
sunanxiang · #1 · 7年之前

都panic 了,你去哪拿返回值啊

EddieChan1993
EddieChan1993 · #2 · 7年之前
sunanxiangsunanxiang #1 回复

都panic 了,你去哪拿返回值啊

我recover捕获到了panic

lee_
lee_ · #3 · 7年之前

return、defer执行顺序应该是:

  1. return要返回值的赋值操作(nil)
  2. defer语句 (这个时间对err赋值已经晚了,因为return将要返回的值已经进行过赋值,nil)
  3. return
    这样的步骤吧,如果想赋值可以这样
    ``` package main

import "fmt"

func main() { fmt.Println(Parse()) }

func Parse()(err error){ defer func() { //选择性的recover switch p := recover(); p { case nil: case "what": err = fmt.Errorf("internal error") fmt.Println(err) default: panic(p)

    }
}()
panic("what")
return err

} ```
具体的可以看这篇博文:https://my.oschina.net/henrylee2cn/blog/505535

sunanxiang
sunanxiang · #4 · 7年之前
EddieChan1993EddieChan1993 #2 回复

#1楼 @sunanxiang 我recover捕获到了panic

对啊,panic然后走到defer 了,不能再去return 了

lee_
lee_ · #5 · 7年之前
lee_lee_ #3 回复

return、defer执行顺序应该是: 1. return要返回值的赋值操作(nil) 2. defer语句 (这个时间对err赋值已经晚了,因为return将要返回的值已经进行过赋值,nil) 3. return 这样的步骤吧,如果想赋值可以这样 ``` package main import "fmt" func main() { fmt.Println(Parse()) } func Parse()(err error){ defer func() { //选择性的recover switch p := recover(); p { case nil: case "what": err = fmt.Errorf("internal error") fmt.Println(err) default: panic(p) } }() panic("what") return err } ``` 具体的可以看这篇博文:https://my.oschina.net/henrylee2cn/blog/505535

package main

import "fmt"

func main() {
    fmt.Println(Parse())
}

func Parse()(err error){
    defer func() {
        //选择性的recover
        switch p := recover(); p {
        case nil:
        case "what":
            err = fmt.Errorf("internal error")
            fmt.Println(err)
        default:
            panic(p)

        }
    }()
    panic("what")
    return err
}
EddieChan1993
EddieChan1993 · #6 · 7年之前
lee_lee_ #5 回复

#3楼 @lee_ ``` package main import "fmt" func main() { fmt.Println(Parse()) } func Parse()(err error){ defer func() { //选择性的recover switch p := recover(); p { case nil: case "what": err = fmt.Errorf("internal error") fmt.Println(err) default: panic(p) } }() panic("what") return err } ```

谢了。正在理解你写的

lee_
lee_ · #7 · 7年之前
EddieChan1993EddieChan1993 #6 回复

#5楼 @lee_ 谢了。正在理解你写的

客气。具体到这段代码,第一步return的赋值应该因为panic跳过了(即便不跳过也不会赋值成功),直接执行了第二步的defer语句

EddieChan1993
EddieChan1993 · #8 · 7年之前
lee_lee_ #7 回复

#6楼 @EddieChan1993 客气。具体到这段代码,第一步return的赋值应该因为panic跳过了(即便不跳过也不会赋值成功),直接执行了第二步的defer语句

我看了你分享的连接,初步理解到了

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