Defer
A defer statement will hold until surrounding function finish executing.
A function literal represents a anonymous function.
They may refer to variables defined in an enclosing function. Such variables :
- are shared between the surrounding function and function literal
- and survived as long as they are accessible
// NewCounter returns a function Count.
// Count prints the number of times it has been invoked.
func NewCounter() (Count func()) {
n := 0
return func() {
n++
fmt.Println(n)
}
}
func main() {
counter := NewCounter()
otherCounter := NewCounter()
counter() // 1
counter() // 2
counter() // 3
otherCounter() // 1 (different n)
otherCounter() // 2
counter() // 4
}
Fibonacci generator using function closure.
Reference : https://www.calhoun.io/5-useful-ways-to-use-closures-in-go/
No matter the receiver receive value or pointer, both value and pointer can use it. We prefer receiver type is pointer due to some reasons:
- The method can modify the value that its receiver points to.
- Avoid copying the value on each method call. This can be more efficient if the receiver is a large struct.
It is like a top level representation, different type implement it, as the interface's initialization.
Three rules :
- A deferred function's arguments are evaluated when the defer statement is evaluated. The deferred call will print 0.
func a() {
i := 0
defer fmt.Println(i)
i++
return
}
- Deferred function calls are executed in Last In First Out order after the surrounding function returns. It will print 3210.
func b() {
for i := 0; i < 4; i++ {
defer fmt.Print(i)
}
}
- Deferred functions may read and assign to the returning function's named return values.
Go believe their declaration style makes the complex declaration more readible.