defer语句
# defer
# 1.1 延迟是什么?
- 即延迟(defer)语句,延迟语句被用于执行一个函数调用,在这个函数之前,延迟语句返回.
# 1.2 延迟函数
- 可以在函数中添加多个
defer
语句.当函数执行到最后时,这些defer
语句会按照逆序执行,最后该函数返回.特别是当在进行一些打开资源的操作时,遇到错误需要提前返回,在返回前需要关闭相应的资源,不然很容易造成资源泄露等问题 - 如果有很多调用
defer
,那么defer
是采用后进先出
模式 - 在离开所在的方法时,执行(报错的时候也会执行)
func ReadWrite() bool {
file.Open("file")
defer file.Close()
if failureX {
return false
} if failureY {
return false
}
return true
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
最后才执行file.Close()
示例代码:
package main
import "fmt"
func main() {
a := 1
b := 2
defer fmt.Println(b)
fmt.Println(a)
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
运行结果:
1
2
1
2
2
示例代码:
package main
import (
"fmt"
)
func finished() {
fmt.Println("Finished finding largest")
}
func largest(nums []int) {
defer finished()
fmt.Println("Started finding largest")
max := nums[0]
for _, v := range nums {
if v > max {
max = v
}
}
fmt.Println("Largest number in", nums, "is", max)
}
func main() {
nums := []int{78, 109, 2, 563, 300}
largest(nums)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
运行结果:
Started finding largest
Largest number in [78 109 2 563 300] is 563
Finished finding largest
1
2
3
2
3
# 1.3 延迟方法
- 延迟并不仅仅局限于函数.延迟一个方法调用也是完全合法的.
示例代码:
package main
import (
"fmt"
)
type person struct {
firstName string
lastName string
}
func (p person) fullName() {
fmt.Printf("%s %s",p.firstName,p.lastName)
}
func main() {
p := person {
firstName: "John",
lastName: "Smith",
}
defer p.fullName()
fmt.Printf("Welcome ")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
运行结果:
Welcome John Smith
1
# 1.4 延迟参数
- 延迟函数的参数在执行延迟语句时被执行,而不是在执行实际的函数调用时执行.
示例代码:
package main
import (
"fmt"
)
func printA(a int) {
fmt.Println("value of a in deferred function", a)
}
func main() {
a := 5
defer printA(a)
a = 10
fmt.Println("value of a before deferred function call", a)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
运行结果:
value of a before deferred function call 10
value of a in deferred function 5
1
2
2
# 1.5 堆栈的推迟
- 当一个函数有多个延迟调用时,它们被添加到一个堆栈中,并在
Last In First Out(LIFO)
后进先出的顺序中执行.
编写一个小程序,它使用一堆defers
打印一个字符串.示例代码:
package main
import (
"fmt"
)
func main() {
name := "Naveen"
fmt.Printf("Orignal String: %s\n", string(name))
fmt.Printf("Reversed String: ")
for _, v := range []rune(name) {
defer fmt.Printf("%c", v)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
运行结果:
Orignal String: Naveen
Reversed String: neevaN
1
2
2
# 1.6defer注意点
# defer函数
- 当外围函数中的语句正常执行完毕时,只有其中所有的延迟函数都执行完毕,外围函数才会真正的结束执行.
- 当执行外围函数中的
return
语句时,只有其中所有的延迟函数都执行完毕后,外围函数才会真正返回. - 当外围函数中的代码引发运行恐慌时,只有其中所有的延迟函数都执行完毕后,该运行时恐慌才会真正被扩展至调用函数.
上次更新: 2024/04/09, 16:48:42
- 01
- AWS NAT-NetWork-Firwalld配置(一)04-09
- 02
- AWS NAT-NetWork-Firwalld配置(二)04-09
- 03
- kubernetes部署minio对象存储01-18