当前位置:网站首页>(10) Defer keyword
(10) Defer keyword
2022-07-28 10:02:00 【Binary cup don't stop】
( Ten )defer keyword
- 1. defer Will be executed before the function returns
- 2. defer It can be placed anywhere in the function
- 3. You can set more than one defer function
- 4. defer The incoming parameters of the function have been defined
- 5. It is mainly used for closing file resources , Database and other connections are closed
golang Medium defer Keyword is used to declare a delay function , This function will be placed in a list , stay defer The system will execute the delay function before the outer function of the statement returns .defer The features are :
- Execute before function returns
- It can be placed anywhere in the function
- You can set more than one defer function , Multiple defer Function execution follows FILO The order
- defer The incoming parameters of the function have been defined
- You can modify the named return value in the function For file resources , Lock resource 、 The database connection is released and closed
- and recover Deal with it together panic
1. defer Will be executed before the function returns
When a program executes a function , The context of the function ( Input parameters , Return value , Output parameters and other information ) As a stack frame, it is placed on the stack of program memory , When the function is finished , Set the return value and return , At this point, the stack frame exits the stack , Function can really complete the execution .
defer The statement function will execute before the function returns , The following program will output B A:
func main() {
defer fmt.Println("A")
fmt.Println("B")
}
2. defer It can be placed anywhere in the function
func main() {
fmt.Println("A")
defer fmt.Println("B")
fmt.Println("C")
}
The above program will output in turn A C B
Be careful :
- defer Statements must be in functions return The statement before , In order for it to work . The following program will only output A
func main() {
fmt.Println("A")
return
fmt.Println("B")
}
- Calling os.Exit When ,defer Not execute . The following program will only output B
func main() {
defer fmt.Println("A")
fmt.Println("B")
os.Exit(0)
}
3. You can set more than one defer function
You can set multiple defer function , Multiple defer Function execution follows FILO The order , The following program will output B D C A
func main() {
defer fmt.Println("A")
fmt.Println("B")
defer fmt.Println("C")
fmt.Println("D")
}
Let's take a look at several defer Nesting :
func main() {
fmt.Println("A")
defer func() {
fmt.Println("B")
defer fmt.Println("C")
fmt.Println("D")
}()
defer fmt.Println("E")
fmt.Println("F")
}
The above program will output : A F E B D C
defer The internal implementation form of the statement is a structure :
# be located /usr/lib/go/src/runtime/runtime2.go#784
type _defer struct {
...
sp uintptr // Function stack pointer ,sp yes stack pointor Word acronyms
pc uintptr // Program counter , pc yes program counter Word acronyms
fn *funcval // Function address , perform defer function
_panic *_panic // Point to the last panic
link *_defer // Point to next _defer structure
...
}
defer The internal implementation is a linked list , The linked list element type is _defer Structure , Among them link The field points to the next _defer Address , When defining a defer At the time of the statement , The system will defer Function to _defer Structure , And put it on the head of the linked list , At the last execution , The system will start from the head of the linked list , This is multiple defer The order of execution is First In Last out Why .
4. defer The incoming parameters of the function have been defined
defer The incoming parameters of the function have been defined , Whether the parameter passed in is a variable 、 expression 、 Function statement , Will first calculate the actual parameter results , Follow again defer Statement stack
func main() {
i := 1
defer fmt.Println(i)
i++
return
}
The above program outputs 1, instead of 2
Be careful :
When defer When using closures , The last value in the loop is always accessed
func main() {
for i:=0; i<5; i++ {
defer func() {
fmt.Println(i)
}()
}
}
The above program outputs continuously 5 individual 5
The solution is to pass the value into the closure function , here defer When the function is put on the stack , Not only the stack address , The incoming parameters will also be recorded , When it is executed, it will print out the value when it is put into the stack
func main() {
for i:=0; i<5; i++ {
defer func(i int) {
fmt.Println(i)
}(i)
}
}
At this time, output in sequence 4 3 2 1 0
5. It is mainly used for closing file resources , Database and other connections are closed
Deal with resource release recycling
adopt defer We can deal with resource recycling simply and gracefully , Avoid complex code logic , Omit and ignore relevant resource recovery issues .
Let's take a look at the following code , The purpose is to copy the contents of the file to a new file
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
dst, err := os.Create(dstName)
if err != nil {
return
}
written, err = io.Copy(dst, src)
dst.Close()
src.Close()
return
}
The above code exists bug Of . When file creation fails , Straight back , However, recycling is not turned off for open file resources .
adopt defer We can ensure that resources can always be shut down correctly , And the processing logic is simple and elegant .
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName)
if err != nil {
return
}
defer src.Close()
dst, err := os.Create(dstName)
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src)
}
and recover Deal with it together panic
recover User capture panic abnormal ,panic Used to throw an exception .recover Need to put in defer In the sentence , Otherwise, it cannot be captured once
The following example will capture panic, And output panic Information
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println(r)
}
}()
panic("it is panic")
}
When multiple panics occur at the same time , Will only catch the first panic
func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println(r)
}
}()
panic("it is panic")
panic("it is another panic")
}
边栏推荐
- Have you ever seen this kind of dynamic programming -- the stock problem of state machine dynamic programming (Part 2)
- Array collation commonly used in PHP
- 哪些字符串会被FastJson解析为null呢?
- ASP. Net core 6 framework unveiling example demonstration [29]: building a file server
- Flink - checkpoint Failure reason: Not all required tasks are currently running
- PHP 获取接口的方式
- Domain events and integration events are not so big
- Include and require include_ Once and require_ Once difference
- 医药行业数字化建设,箭在弦上
- pkg打包node工程
猜你喜欢

医药行业数字化建设,箭在弦上

Some problems about CLR GC tuning

NTU Lin Xuantian's "machine learning cornerstone" problem solving and code implementation | [you deserve it]

Software testing and quality learning notes 2 - black box testing

Learn a hammer.Net zero foundation reverse tutorial lesson 3 (shell and homework)

How to get more marks in the game under the new economic model of Plato farm

In the era of home health diagnosis, Senzo creates enhanced lateral flow test products

老板:公司系统太多,能不能实现账号互通?

多线程一定能优化程序性能吗?

Standing on the shoulders of big men, you can see further
随机推荐
Create SSL certificate using OpenSSL
Set of bus related concepts
[collection] linear algebra let me think - Summary of chapter topics
In the era of home health diagnosis, Senzo creates enhanced lateral flow test products
3 minutes to tell you how to become a hacker | zero foundation to hacker getting started guide, you only need to master these five abilities
在Plato Farm新经济模型下,如何在游戏中获取更多MARK
高温持续,公交企业开展安全专项培训
Today, I want to talk about the data types of MySQL database
EvaluatorFilter简介说明
Pulse style | exclusive interview with Committee -- Tencent engineer Zhang Dawei calls you to eat "crab"
备受关注的Bit.Store,最新动态一览
多线程一定能优化程序性能吗?
How to get more marks in the game under the new economic model of Plato farm
高温天气筑牢安全生产防线,广州海珠区开展加油站应急演练
Mock.js
redis的基础知识
7.27 最小生成树阶段性测试题解
Symbolic operation of MATLAB
Basic knowledge of redis
每天在岗不足8小时被辞?腾讯前员工追讨1300万加班费等,法院终审获赔9万