"Static" variables in Go.
Continuation of the Scope and Closures in Go.
In C programming language, objects have a storage duration that determines their lifetime. Altogether, four storage durations are available: automatic, static, thread, and allocated. Objects of automatic storage duration are declared within a block or as a function parameter. The lifetime of these objects begins when the block in which they’re declared begins execution, and ends when execution of the block ends. If the block is entered recursively, a new object is created each time, each with its own storage.
Objects declared in file scope have static storage duration. The lifetime of these objects is the entire execution of the program, and their stored value is initialized prior to program startup. We can also declare a variable within a block scope to have static storage duration by using the storage class specifier static, as shown in the example below:
File static.c
Here, a static variable x is defined in the function func. Each time the function is called, the value of x is incremented by 2 and is returned to the client code, in our case to the function assert. This object persists even after the func has exited.
There is no such concept like storage classes neither static keyword in Go, yet based on what was told in one of the previous articles, we can implement similar functionality (though based on different mechanics).
Files go_sketches.go, sketches_test.go
Here, function ClosureStatic accepts an integer argument i; inside ClosureStatic a closure function is defined. This closure increments provided argument i by 2. When a calling function is exited, an object identified by i persists and keeps its value in defferent lexical scopes, that can be seen in the test where ClosureStatic produces expected value when called from different functions - testing function itself and staticCaller. At the same time, there is no way a caller can change the "static" variable.
Such approach might be useful when we need a global object to persist throughout the whole program. At the same time, once created, such object can not be changed or re-instantiated by a calling code. This is aligned with the concepts of encapsulation and loose coupling.