I was thinking about defer for the processing that I wanted to execute at the end of the function, but I tried to dig deeper into defer to understand it properly.
--If you describe the process with defer, it will be executed at the end of func. --In the example below, "Today" is executed and the end of func is reached, so "Friday." Is executed after that.
func hogehoge() {
defer fmt.Println("It's Friday.")
fmt.Println("today....")
}
today....
It's Friday.
According to the explanation of Tour of Go
There is an explanation. I can understand 1 somehow, but I was curious about the description of 2 ** "immediately evaluated" **, so I would like to explain it in detail later.
Also, according to the explanation of Programming Language Go
There is an explanation to that effect. The following is an example.
resp, err := http.Get(url)
defer resp.Body.Close() //Actually, error judgment should be put before defer
In Java, close () is often written at the end of the function, and sometimes I forget to write close (), but If it is go, it is recommended to put the release process immediately after acquiring the resource using defer.
I think it's faster to actually look at the code, so take a look at the sample below.
func main() {
defer today()()
fmt.Println("today....")
}
func today() func() {
fmt.Println("Is it Friday?")
return func() {fmt.Println("Or is it Saturday?")}
}
What if you do this?
Since defer is called at the end of main, `today ...`
is called first, then ``` Friday in today ()? `, Finally`
or Saturday? You might wonder if it's going to be `` `.
But when I try it
Is it Friday?
today....
Or is it Saturday?
It becomes. Why? The point is that the return value of today () is functional.
The argument of the ** defer call in the previous section is evaluated immediately, but please pay attention to the part **.
defer today()()
The evaluation is carried out in the description part of.(Why are there two parentheses? You may think for a moment, but I would like to explain at the end because the story is off.)
So
fmt.Println("Is it Friday?")
Is executed. After that, proceed to the processing in main
fmt.Println("today....")
Is executed.
Then with delayed execution
fmt.Println("Or is it Saturday?")
It is a flow.
Doesn't it have 2 parentheses? ?? You might think, but this is necessary. What happens if you try using one parenthesis?
func main() {
defer today()
fmt.Println("today....")
}
func today() func() {
fmt.Println("Is it Friday?")
return func() {fmt.Println("Or is it Saturday?")}
}
today....
Is it Friday?
The order has changed and Saturday is gone. .. .. ..
defer today() //1
defer today()() //2
The two descriptions are fundamentally different.
1 is just the process of defer and executes the today function. That is, today at the end of the main function()Is executed. In this process, the anonymous function is returned, but the anonymous function is not executed.
On the other hand, 2 is today()The function returned in is executed at the end of the main function. To make it easy to understand, 2 is an anonymous function in the processing of defer.func() {fmt.Println("Or is it Saturday?")}
Is running.