一尘不染

如何在恐慌的Go函数中返回值?

go

我的Go函数应该返回一个值,但是在调用库函数时可能会出现紧急情况。我可以recover()在延迟调用中捕获它,但是在这种情况下如何返回一个值?

func MyFunc() string{
    defer func() {
        if err := recover(); err != nil {
            // What do I do to make MyFunc() return a value in case of panic?
        }
    }()
    SomeFuncThatMayPanic()
    return "Normal Return Value"
    // How can I return "ERROR" in case of panic?
}

阅读 274

收藏
2020-07-02

共1个答案

一尘不染

您可以使用命名结果参数。命名您的返回值,并在检测到紧急情况时在延迟函数中更改返回“变量”的值。更改后的新值将被返回。

例:

func main() {
    fmt.Println("Returned:", MyFunc())
}

func MyFunc() (ret string) {
    defer func() {
        if r := recover(); r != nil {
            ret = fmt.Sprintf("was panic, recovered value: %v", r)
        }
    }()
    panic("test")
    return "Normal Return Value"
}

输出(在Go Playground上尝试):

Returned: was panic, recovered value: test

Spec:Defer语句中 提到了这一点:

例如,如果延迟函数是函数文字,并且周围函数已命名结果参数在文字范围内,则延迟函数可以在返回结果参数之前对其进行访问和修改。

博客文章 Defer,Panic and Recover中 也提到了这一点:

延迟函数可以读取并分配给返回函数的命名返回值。

有效的Go中:Recover

如果出现doParse紧急情况,恢复块会将返回值设置为— nil延迟函数可以修改命名的返回值。

2020-07-02