在Go中使用defer [英] Use of defer in Go

查看:91
本文介绍了在Go中使用defer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

defer在Go中的用途是什么?语言文档说它在周围的函数返回时执行.为什么不将代码放在给定函数的末尾?

What is the use of defer in Go? The language documentation says it is executed when the surrounding function returns. Why not just put the code at end of given function?

推荐答案

我们通常使用defer关闭或释放资源.

We usually use defer to close or deallocate resources.

周围的函数会在返回前执行所有延迟的函数调用,即使它会死机.如果只是将函数调用放在周围函数的末尾,则在发生紧急情况时会跳过该调用.

A surrounding function executes all deferred function calls before it returns, even if it panics. If you just place a function call at the end of a surrounding function, it is skipped when panic happens.

此外,延迟的函数调用可以通过调用recover内置函数来处理紧急情况.这不能通过在函数末尾进行普通函数调用来完成.

Moreover a deferred function call can handle panic by calling the recover built-in function. This cannot be done by an ordinary function call at the end of a function.

每个延迟调用都放在堆栈上,并在周围函数结束时以相反的顺序执行.颠倒顺序有助于正确分配资源.

Each deferred call is put on stack, and executed in reverse order when the surrounding function ends. The reversed order helps deallocate resources correctly.

要调用一个函数,必须达到defer语句.

The defer statement must be reached for a function to be called.

您可以将其视为实现try-catch-finally块的另一种方式.

You can think of it as another way to implement try-catch-finally blocks.

try-finally一样关闭:

func main() {
    f, err := os.Create("file")
    if err != nil {
        panic("cannot create file")
    }
    defer f.Close()
    // no matter what happens here file will be closed
    // for sake of simplicity I skip checking close result
    fmt.Fprintf(f,"hello")
}

诸如try-catch-finally

func main() {
    defer func() {
        msg := recover()
        fmt.Println(msg)
    }()
    f, err := os.Create(".") // . is a current directory
    if err != nil {
        panic("cannot create file")
    }
    defer f.Close()
    // no matter what happens here file will be closed
    // for sake of simplicity I skip checking close result
    fmt.Fprintf(f,"hello")
}

与try-catch-finally相比,好处是没有块和变量作用域的嵌套.这简化了周围功能的结构.

The benefit over try-catch-finally is that there is no nesting of blocks and variable scopes. This simplifies the structure of the surrounding function.

就像finally块一样,如果延迟函数调用可以到达返回的数据,则它们也可以修改返回值.

Just like finally blocks, deferred function calls can also modify the return value if they can reach the returned data.

func yes() (text string) {
    defer func() {
       text = "no"
    }()
    return "yes"
}

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

这篇关于在Go中使用defer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆