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主要是需要拖延的时效性,类似闹钟能做到提醒的作用。
常用的场合如下:
像是把使用在读档後的关档,这样也不会忘记。
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()
两个defer执行的优先顺序,为了要贯彻拖延的行为,越早分派的任务要越晚达成才行。
package main
import (
"fmt"
)
func main() {
defer print1()
defer print2()
}
func print1() {
fmt.Println("p1")
}
func print2() {
fmt.Println("p2")
}
执行後可得以下结果
p2
p1
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
package main
import (
"fmt"
"os"
)
func main() {
defer func() {
fmt.Println("output")
}()
os.Exit(0)
}
执行後可得以下结果
由於程序先执行了os.Exit(0)
,导致後面的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
defer是个很简单的观念,但里头却包含着许许多多较不直观的地雷,也因此特意开一章节来替大家厘清排雷! 希望以後不会误踩地雷。
此篇会介绍 Bootstrap 客制化所需的环境设置。 想先谈谈关於 Bootstrap 5 客制...
今天大概会聊到的范围 recompose 在整个系列文章中,有提过不只一次的 recomposit...
昨天我们利用 GAS 读取了筛选邮件的内容 今天我们要进一步将资料存到 Google Sheet 以...
近水楼台先得月 tags: IT铁人 区域性原则 有在组装电脑的人就会知道,电脑的储存装置包括记忆体...
Data Storage in iOS 数据持久性( Data Persistence ) 是将任何...