How to make method return value if panic happen and processed in defer func(){…}() in golang

huangapple go评论79阅读模式
英文:

How to make method return value if panic happen and processed in defer func(){...}() in golang

问题

我的功能必须无论成功还是发生恐慌都返回一个字符串。

func getDBStoreStatus() string {
    var replyMessage string
    defer func() string {
        if err := recover(); err != nil {
            replyMessage = "发生错误。"
        }
        return replyMessage
    }()

    // 将行存储到数据库中
    db, err := sql.Open("mysql", "user1:password@/databaseName?charset=utf8")
    newMessage, err := db.Prepare("INSERT .............")
    res, err := newMessage.Exec(...........)
    if err != nil {
        panic(err)
    }
    replyMessage = "OK"
    return replyMessage
}

如果恐慌在 defer 部分被处理,我该如何返回一个字符串?你可以看到 defer 部分的 return 语句无法正常工作。

英文:

My function must return a string whatever success or panic.

func getDBStoreStatus() string{
    var replyMessage string
    defer func() string{ 
        if err := recover(); err != nil {  
            replyMessage = "Error happend." 
        }
    return replyMessage
    }()

    //do something to store row into DB
    db, err := sql.Open("mysql", "user1:password@/databaseName?charset=utf8") 
    newMessage, err := db.Prepare("INSERT .............
    res, err := newMessage.Exec(...........
    if err != nil { 
        panic(err)
    }
    replyMessage = "OK"
    return replyMessage
}

How can I return a string, if the panic processed by defer section?
You can see the return statement in defer section doesn't work properly.

答案1

得分: 1

给你的返回参数命名,然后你可以在defer方法中设置它:

func getDBStoreStatus() (replyMessage string) {
    defer func(){ 
        if err := recover(); err != nil {  
            replyMessage = "Error happend." 
        }
    }()

    //do something to store row into DB
    db, err := sql.Open("mysql", "user1:password@/databaseName?charset=utf8") 
    newMessage, err := db.Prepare("INSERT .............")
    res, err := newMessage.Exec(...........)
    if err != nil { 
        panic(err)
    }
    replyMessage = "OK"
    return replyMessage
}

参考Go博客上的Defer, Panic and Recover

  1. 延迟函数可以读取和赋值给返回函数的命名返回值。

在这个例子中,延迟函数在包围函数返回后递增返回值i。因此,这个函数返回2:

func c() (i int) {
    defer func() { i++ }()
    return 1
}

不过我真的看不出有什么意义。你可以直接这样做:

if err != nil { 
    return "Error happend."
}

而不是使用panic(err)

英文:

Name your return parameter, then you can set it in the defer method:

func getDBStoreStatus() (replyMessage string) {
    defer func(){ 
        if err := recover(); err != nil {  
            replyMessage = "Error happend." 
        }
    }()

    //do something to store row into DB
    db, err := sql.Open("mysql", "user1:password@/databaseName?charset=utf8") 
    newMessage, err := db.Prepare("INSERT .............
    res, err := newMessage.Exec(...........
    if err != nil { 
        panic(err)
    }
    replyMessage = "OK"
    return replyMessage
}

See the Go Blog post on Defer, Panic and Recover:

> 3. Deferred functions may read and assign to the returning function's named return values.
>
> In this example, a deferred function increments the return value i
> after the surrounding function returns. Thus, this function returns 2:
>
> func c() (i int) {
> defer func() { i++ }()
> return 1
> }

I don't really see the point, though. You could just do:

    if err != nil { 
        return "Error happend."
    }

instead of panic(err).
1: http://blog.golang.org/defer-panic-and-recover

huangapple
  • 本文由 发表于 2016年2月25日 11:32:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/35617709.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定