2.3.4 Life cycle of variables

The Go language has an automatic garbage collector that automatically manages the life cycle of variables. So how does the garbage collector know when a variable can be collected?

The basic idea is to start with each package-level variable and each local variable of each currently running function and iterate through the access path of a pointer or reference to see if the variable can be found. If there is no such access path, then the variable is unreachable, that is, the existence of the variable does not affect the calculation results of subsequent programs.

Since the effective period of a variable depends only on reachable, a local variable declaration period may exceed the local scope. Also, local variables may persist after the function returns.

The compiler also automatically selects whether to allocate storage space for local variables on the stack or on the heap. And, unlike In Java, this choice is not made by declaring variables as var or new.

var global *int

func f(a) {
    var x int
    x = 1
    global = &x
} 
func g(a) {
    y := new(int)
    *y = 1
}
Copy the code

The x variable in f must be allocated on the heap because it is still available after the function exits through the package-level global variable, even though it is defined inside the function. In Go terminology, the local x variable escapes from the function f. Conversely, when g returns, the variable *y will be unreachable, which means it can be reclaimed immediately. Therefore, *y does not escape from g, and the compiler can choose to allocate *y on the stack, albeit in a new way. In fact, you don’t need to worry about escaping variables to write the right code at all times, but remember that escaping variables require extra memory allocation and can have a subtle impact on performance optimization.

Go’s automatic garbage collector is a great help in writing the right code, but it doesn’t mean you don’t have to worry about memory at all. You don’t need to explicitly allocate and free memory, but to write efficient programs you still need to understand the lifetime of variables. For example, saving Pointers to short-life objects in long-life objects, especially global variables, prevents garbage collection of short-life objects (and thus may affect program performance).

2.4. Assignment

As with any other language, there are the following assignment methods

x = 1 // Assign a named variable
*p = true // Assign indirectly through a pointer
person.name = "bob" Struct field assignment
count[x] = count[x] * scale // Array, slice, or map element assignment
count[x] *= scale // This is equivalent to the above
Copy the code

But GO supports increment and decrement statements, and this increment and decrement is not an expression. For example:

i := 1
var j int
i++ / / right
i-- / / right
j = i++ / / error
Copy the code

2.4.1. Tuple assignment