Control flow
defer will defer function execution on end of parent function but before parent returns
// output:
// End
// Start
func main() {
defer fmt.Println("Start")
fmt.Println("End")
}
Deferred functions run in LIFO Last In First Out
// output:
// End
// Middle
// Start
func main() {
defer fmt.Println("Start")
defer fmt.Println("Middle")
defer fmt.Println("End")
}
Arguments evaluated at time defer is executed, not at time of called function execution
// output: start
func main() {
a := "start"
defer fmt.Println(a)
a = end
}
Deferred function will be executed before panic:
// output
// start
// deferred
// panic: error happened
func main() {
fmt.Println("start")
defer fmt.Println("deferred")
panic("error happened")
}
panic stops function execution on exactly place where called. In the next example "stop panic" wouldn't be printed
// Output:
// start
// about to panic
// Error: Error happened
// end
func main() {
fmt.Println("start")
panicker()
fmt.Println("end")
}
func panicker() {
fmt.Println("about to panic")
defer func(){
if err := recover(); err != nil {
log.Println("Error: ",err)
}
}()
panic("Error happened")
fmt.Println("stop panic")
}
there is recover function that can be used to recover from panics. Only useful in deferred functions(because they are executed right before panic)