The interview questions

This is part 5 of the Go Quiz series, which examines the semantics of defer in the Go language, and part 2 of the defer semantics.

If you haven’t seen Defer 1, please review: Go defer Semantics 1.

The title of this article is as follows:

package main func bar() (r int) { defer func() { r += 4 if recover() ! = nil { r += 8 } }() var f func() defer f() f = func() { r += 2 } return 1 } func main() { println(bar()) }Copy the code
  • A: 1
  • B: 7
  • C: 12
  • D: 13
  • E: 15

Compared with the topic in the first part of defer, this question mainly inspects the following points:

  • bedeferWhen was the value of the function of?Pay attention toThis is the value of the function, not the parameter of the function.
  • If the value of the function is zeronilthatdeferWhat happens to a nil function?
  • Multiple wasdeferThe order in which functions are executed follows the LIFO principle.
  • deferrecoverCombining can capturepanic.
  • deferWhat happens if I change the named return value parameter of a function?

parsing

Function value

Function value refers to the value of a function. For those of you who are new to Go, let me explain the concept.

First, a function is a type, like struct, int, etc.

We can first define a function type, then declare a variable of that function type, and assign a value to that variable. The value of the function type variable can then be called the function value. Take a look at the following code example to make it clear.

FuncType type FuncType func(int) int // Define variable f1, FuncType var f1 FuncType = func(a int) int {return a} // Define a variable f, the type is a function type, the function signature is func(int) int // Assign f in main, Var f func(int) int func main() {fmt.println (f1(1)) // define variable f2, FuncType var f2 FuncType f2 = func(a int) int {a++ return a} fmt.Println(f2(1)) // Assign a value to f of function type f = func(a int) int {  return 10 } fmt.Println(f(1)) }Copy the code

When we usually implement functions, we usually do the type definition, function variable and variable assignment together.

Function variables that are declared but not initialized are nil, which means that the default value is nil.

We know from the above example that we can define the function type first and then the variables of the function type.

The principle of analytic

Let’s review what the official document says:

Each time a “defer” statement executes, the function value and parameters to

the call are evaluated as usual and saved anew but the actual function is not

invoked.

Instead, deferred functions are invoked immediately before the

surrounding function returns, in the reverse order they were deferred.

That is, if the surrounding function returns through an explicit return statement,

deferred functions are executed after any result parameters are set by that

return statement but before the function returns to its caller.

If a deferred function value evaluates to nil, execution panics when the function is

invoked, not when the “defer” statement is executed.

The bar() function in this code is executed in the following order before return

So the answer is 13 and the answer is D.

conclusion

In the first article we listed the six principles of defer, refer to the six principles of Go Defer semantics.

In this article, I summarize two other considerations for the semantics of defer covered in this topic:

  • The function value that was deferred is determined as soon as the defer statement is executed.

    Package main import "FMT" func main() {defer func() {r := recover() fmt.println (r)}() var f func(int) // f did not initialize the assignment, The default is nil defer f(1) // The function variable f has been determined to be nil f = func(a int) {}}Copy the code
  • If the function or method deferred is nil, no errors are reported when the defer statement is executed, but panic: Runtime error is raised when the nil function or method is called at the end: Invalid memory address or nil pointer dereference.

To consider

What is the result of running the following problem? Leave your answers in the comments section. You can also send the message DEFER2 on my WX public number to get the answer and why.

Topic 1: What is the result of the program?

package main

import "fmt"

func main() {
    defer func() {
        fmt.Print(recover())
    }()
    defer func() {
        defer fmt.Print(recover())
        defer panic(1)
        recover()
    }()
    defer recover()
    panic(2)
}
Copy the code

Open source address

Article and sample code open source address at GitHub: github.com/jincheng9/g…

Public id: coding advanced

Personal website: Jincheng9.github. IO /

Zhihu: www.zhihu.com/people/thuc…

Good article recommendation

  1. Will the function deferred be executed?
  2. Go Quiz: The basic principles and considerations of Slice from the Go interview questions
  3. Go Quiz: What should channel pay attention to from the Go interview questions
  4. Go Quiz: The semicolon rule and switch considerations from the Go interview questions
  5. Go Quiz: Look at the underlying principles and considerations of the semantics of defer from the Go interview question
  6. Does Go have reference variables and reference passing? Are map,channel, and slice passed by reference as function arguments?
  7. What is the difference between using new and make?
  8. Official tutorial: Get Started with Go Generics
  9. Read Go generic design and usage scenarios
  10. This article reads the usage scenario of Go anonymous structure

References

  • Go101.org/quizzes/def…
  • Github.com/jincheng9/….
  • Github.com/jincheng9/….
  • golang.google.cn/ref/…