Day13 Defer

defer

A defer statement defers the execution of a function until the surrounding function returns.
推迟执行defer的叙述式,尽可能地拖拖拖等等等,直到目前所在的func打烊结束要回传时才做事。

defer是延迟执行的意思,主要用於宣告function结束前的动作

延迟执行的意思如下

package main

import (
	"fmt"
)

var a = 50

func main() {
	defer add_a()
	fmt.Println(a)
}

func add_a() {
	a += 100
}

执行後结果如下

50

你可以发现我们是先执行Println才执行add_a()

程序会用到defer主要是需要拖延的时效性,类似闹钟能做到提醒的作用。

Close File throuth defer

常用的场合如下:

像是把使用在读档後的关档,这样也不会忘记。

f, err := os.Open("test.txt")
if err != nil {
    return err
}
defer f.Close()

也常运用在关闭channel关闭DB之中。

db, err := sql.Open("mysql", "USER:PASSWORD@/DB")
	if err != nil {
		log.Fatalln(err)
	}
	defer db.Close()

Executing order of defer

两个defer执行的优先顺序,为了要贯彻拖延的行为,越早分派的任务要越晚达成才行。

defer的执行顺序

package main

import (
	"fmt"
)

func main() {
	defer print1()
	defer print2()
}

func print1() {
	fmt.Println("p1")
}

func print2() {
	fmt.Println("p2")
}

执行後可得以下结果

p2
p1

修改defer中的参数

package main

import (
	"fmt"
)

func main() {
	assign2(50)
}

func assign2(a int) int {
	defer fmt.Println(a) 
	a = 100              
	return a
}

执行後可得以下结果

50
package main

import (
	"fmt"
)

func main() {
	assign1(50)
}

func assign1(a int) int {
	a = 100
	defer fmt.Println(a)
	return a
}

执行後可得以下结果

100

defer with os.Exit()

package main

import (
	"fmt"
	"os"
)

func main() {
	defer func() {
		fmt.Println("output")
	}()
	os.Exit(0)
}

执行後可得以下结果


由於程序先执行了os.Exit(0),导致後面的defer不会被执行。

Anonymous Function with defer

package main

import (
	"fmt"
)

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

func func1() int {
	var a int
	defer func() {
		a = 100
	}()
	return a
}

执行後可得以下结果

0
func main() {
	fmt.Println(func2())
}

func func2() (a int) {
	a = 50
	defer func() {
		a = 100
	}()
	return a 
}

执行後可得以下结果

100

看得出上述两个范例的差异了麻?

差别在於一个func1不指定要回传哪个int变数,但func2指定要回传a变数!

也因此,func1在直接return的时候,由於并未指定要a,因此defer就让return先执行。

func2指定要a变数了,因此defer发现它必须要执行完赋予a值的任务才能让他return

Summary

defer是个很简单的观念,但里头却包含着许许多多较不直观的地雷,也因此特意开一章节来替大家厘清排雷! 希望以後不会误踩地雷。


<<:  IT铁人DAY 13-Composite 组合模式

>>:  Day14_HTML语法11

第 13 集:Bootstrap 客制化 Sass 环境

此篇会介绍 Bootstrap 客制化所需的环境设置。 想先谈谈关於 Bootstrap 5 客制...

D24 / 什麽时候我的 Composable function 会重新被呼叫 - recompose

今天大概会聊到的范围 recompose 在整个系列文章中,有提过不只一次的 recomposit...

利用 Google App Script 将资料存到 Google Sheet(1)

昨天我们利用 GAS 读取了筛选邮件的内容 今天我们要进一步将资料存到 Google Sheet 以...

Day-10 近水楼台先得月

近水楼台先得月 tags: IT铁人 区域性原则 有在组装电脑的人就会知道,电脑的储存装置包括记忆体...

Day25 Data Storage in iOS 01 - UserDefaults

Data Storage in iOS 数据持久性( Data Persistence ) 是将任何...