網頁

2021/6/14

Golang 延遲敘述 defer statements

Go語言的defer關鍵字的延遲敘述特性如下。


Defer statement的函式在回傳後才被執行,但被defer的函式參數是於當下決定而非回傳後才決定。

例如下面先印出"hello",然後才印"world"。

package main

import "fmt"

func main() {
    s := "world"
    defer fmt.Println(s) // defer statement
    s = "go"
    fmt.Println("hello")
}

執行印出以下。

hello
world


每個defer statment會放入stack中,是以後進先出(last-in-first-out, LIFO)的順序執行。

例如下面有三個defer statements。

main.go

package main

import "fmt"

func main() {
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
}

執行印出以下,最後的defer statement最先被執行。

3
2
1


Defer會讀取並修改有名稱的回傳變數值。

雖然defer statement於return後才執行,但讀取及修改有名稱的回傳變數值是回傳後的值。

例如下面執行結果印出2。當c()執行時:

  1. 有名稱的回傳變數i初值為0。
  2. return時i為1。
  3. defer statement的i在執行前為return的1,執行i++後為2,所以最終c()回傳值為2。
package main

import "fmt"

func main() {
    i := c()
    fmt.Println(i)
}

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

沒有留言:

張貼留言