Go實戰--golang中defer的使用(有事沒事defer一下)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

生命不止,繼續 go go go !!!

學習golang這麼久了,還沒看到類似傳統的 try…catch…finally 這種異常捕捉方式。
但是,Go中引入的Exception處理:defer, panic, recover。

那麼今天跟大家分享一下golang中的defer。閑言少敘,看一下defer的作用:

Defer is used to ensure that a function call is performed later in a program’s execution, usually for purposes of cleanup. defer is often used where e.g. ensure and finally would be used in other languages.

defer的思想類似於C++中的解構函式,不過Go語言中“析構”的不是對象,而是函數,defer就是用來添加函數結束時執行的語句。注意這裡強調的是添加,而不是指定,因為不同於C++中的解構函式是靜態,Go中的defer是動態。

引自:http://www.cnblogs.com/ghj1976/archive/2013/02/11/2910114.html

說多無用,想來個開胃菜,看看如何使用:

package mainimport "fmt"func main() {    defer goodbye()    defer goodnight()    fmt.Println("Hello world.")}func goodnight() {    fmt.Println("GoodNight")}func goodbye() {    fmt.Println("Goodbye")}

輸出:
Hello world.
GoodNight
Goodbye

看出什麼了嗎?
**defer在函數結束之前執行
多個defer的執行順序: Multiple defers are stacked last-in first-out so that the most recently deferred function is run first.**

那麼defer之前就return了呢?

package mainimport "fmt"func main() {    fmt.Println("Hello world.")    return    defer goodbye()    defer goodnight()}func goodnight() {    fmt.Println("GoodNight")}func goodbye() {    fmt.Println("Goodbye")}

輸出:
Hello world.
defer是在return之前執行的

defer用於關閉檔案

package mainimport "fmt"import "os"func main() {    f := createFile("/tmp/defer.txt")    defer closeFile(f)    writeFile(f)}func createFile(p string) *os.File {    fmt.Println("creating")    f, err := os.Create(p)    if err != nil {        panic(err)    }    return f}func writeFile(f *os.File) {    fmt.Println("writing")    fmt.Fprintln(f, "data")}func closeFile(f *os.File) {    fmt.Println("closing")    f.Close()}

defer用於鎖

func Divide(i int) error {    mu.Lock()    defer mu.Unlock()    if i == 0 {        return errors.New("Can't divide by zero!")    }    val /= i    return nil}

defer中的坑兒

看下面的代碼:

package mainimport (    "fmt")func main() {    fmt.Println(f())    fmt.Println(f1())    fmt.Println(f2())}func f() (result int) {    defer func() {        result++    }()    return 0}func f1() (r int) {    t := 5    defer func() {        t = t + 5    }()    return t}func f2() (r int) {    defer func(r int) {        r = r + 5    }(r)    return 1}

輸出:
1
5
1

要使用defer時不踩坑,最重要的一點就是要明白,return xxx這一條語句並不是一條原子指令!
函數返回的過程是這樣的:先給傳回值賦值,然後調用defer運算式,最後才是返回到調用函數中。
defer運算式可能會在設定函數傳回值之後,在返回到調用函數之前,修改傳回值,使最終的函數傳回值與你想象的不一致。
出自:https://tiancaiamao.gitbooks.io/go-internals/content/zh/03.4.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.