Skip to content

Instantly share code, notes, and snippets.

@vladfr
Last active February 6, 2022 11:18
Show Gist options
  • Save vladfr/6083f5e02c50bf1ef04804f169948afa to your computer and use it in GitHub Desktop.
Save vladfr/6083f5e02c50bf1ef04804f169948afa to your computer and use it in GitHub Desktop.
Go defer order explained
// This example shows how Go executes deferred statements in relation to a return
//
// This will output:
//
// Setting string to My first program says:
// Setting string to 3. Hello
//Setting string to 2. world
// Setting string to 1. from Deferred Go
// In main(), deferred() returned 3. Hello
// but str is now 1. from Deferred Go
package main
import "fmt"
// we use a global string to simplify things
var str string
//deferred shows the call order of defer and return statements
func deferred() string {
// defer statements are called last in, first out
// so this statement will be called last
defer setStr("1. from Deferred Go")
// another defer, this will be called right after
// our function returns
defer setStr("2. world")
// when we reach return, setStr() will be added onto the call stack
// its return value will be retained here
// but it won't return right away
// because we have defer'd statements to execute
return setStr("3. Hello")
}
//setStr both sets the string and prints it, so we can see the order on the call stack
func setStr(s string) string {
str = s
fmt.Println("Setting string to ", str)
return str
}
func main() {
// our simple setStr function works normally
setStr("My first program says:")
// let's capture the return value
returnValue := deferred()
// the return value will be "3. Hello", just as deferred() returns
fmt.Println("In main(), deferred() returned", returnValue)
// but due to the defer statements, str will now hold another value
// why is (str == "1. from Deferred Go") true?
fmt.Println("but str is now ",str)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment