1. 程式人生 > >Go Defer Simplified with Practical Visuals

Go Defer Simplified with Practical Visuals

Deferred methods

You can also use methods with defer. However, there’s a quirk. Watch.

Without pointers

type Car struct {
model string
}
func (c Car) PrintModel() {
fmt.Println(c.model)
}
func main() {
c := Car{model: "DeLorean DMC-12"}
  defer c.PrintModel()

Output

DeLorean DMC-12

With pointers

func (c *Car) PrintModel() {
fmt.Println(c.model)
}

Output

Chevrolet Impala

What’s going on?

Remember that the passed params to a deferred func are saved aside immediately without waiting the deferred func to be run.

So, when a method with a value-receiver is used with defer, the receiver will be copied (in this case Car) at the time of registering and the changes to it wouldn’t be visible (Car.model

). Because, the receiver is also an input param and evaluated immediately to “DeLorean DMC-12” when it’s registered with the defer.

On the other hand, when the receiver is a pointer, when it’s called with defer, a new pointer is created but the address it points to would be the same with the “c” pointer above. So, any changes to it would be reflected flawlessly.