🏓

defer基本使い方

2023/05/03に公開

基本的な使用方法

deferキーワードは通常、リソースのオープン後に配置され、後でリソースを閉じることを忘れないようにします。
deferで宣言されたコードは、実際には関数が終了するまで実行されません。

func demo_defer_0() {
	fileName := "./test.txt"
	f, _ := os.OpenFile(fileName, os.O_RDONLY, 0)
	defer f.Close()

	contents, _ := ioutil.ReadAll(f)
	fmt.Println(string(contents))
}

複数のdefer呼び出しの順序:先入れ後出し(FILO)

func demo_defer_1() {
	for i := 0; i < 3; i++ {
		defer fmt.Println("defer:", i)
	}
}

// defer: 2
// defer: 1
// defer: 0

スコープは現在の関数に制限されます


異なる関数には異なる関数スタックがあります。

func demo_defer_2() {
	func() {
		defer fmt.Println(1)
		defer fmt.Println(2)
	}()

	fmt.Println("defer action")

	func() {
		defer fmt.Println("a")
		defer fmt.Println("b")
	}()
}

// 2
// 1
// defer action
// b
// a

deferの後の関数パラメータは値渡しです

func demo_defer_3_1() {
	num := 0
	defer func(n int) {
		fmt.Println("defer:", n)
	}(num)

	for i := 0; i < 10; i++ {
		num++
	}

	fmt.Println(num)
}


// 10
// defer: 0
func demo_defer_3_2() {
	num := 0
	p := &num
	defer func(p *int) {
		fmt.Println("defer:", *p)
	}(p)

	for i := 0; i < 10; i++ {
		num++
	}

	fmt.Println(*p)
}

// 10
// defer: 10
func demo_defer_3_3() {
	num := 0
	defer func() {
		fmt.Println("defer:", num)
	}()

	for i := 0; i < 10; i++ {
		num++
	}

	fmt.Println(num)
}

// 10
// defer: 10

returnはdeferより先に実行されます

func demo_defer_4_1() (int, error) {
	defer fmt.Println("defer")
	return fmt.Println("return")
}

// return
// defer
func demo_defer_4_2() (num int) {
	num = 10
	defer func() {
		num += 5
	}()

	return 2
}

// 7

最初に(num int)で、numは初期値0です。
その後、num = 10として、値が10に設定されます。
次に、return 2で、numが2に設定されます。
最後に、deferの中でnumが計算され、結果は7です。

func demo_defer_4_3() int {
	num := 10
	defer func() {
		num += 5
	}()

	return 2
}

// 2

ここでは、numとreturnの値は関連していません。

panicが発生した場合、既に宣言されたdeferはスタックから実行されます

func demo_defer_5_1() {
	defer fmt.Println(1)
	defer fmt.Println(2)
	defer fmt.Println(3)

	panic("panic call")

	defer fmt.Println(4) // 実行されません
}
func demo_defer_5_2() {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println(err)
		}
	}()

	panic("panic call")
}

株式会社ブレイブスタジオ
Bravestudio Inc.

Discussion

ログインするとコメントできます