post image January 6, 2022 | 2 min Read

Go defer

package main

import (
	"fmt"
	// "strconv"
	// "math"
	// "reflect"
	// "math"
	"io/ioutil"
	"log"
	"net/http"
)

func simpleFunc()  {
	fmt.Printf("start\n")
	fmt.Printf("middle\n")
	fmt.Printf("end\n")
}

func simpleFuncWithdeferKeyWord()  {
	fmt.Printf("start\n")
	// defer keyword postpones line execution but
	// it does not move it at the end (after main function is done), it simply 
	// checks if there are any "defered" lines and
	// it executes them before it "returns" !!!
	defer fmt.Printf("middle\n")
	fmt.Printf("end\n")
}


func simpleFuncWithdeferKeyWordEverywhere()  {
	defer fmt.Printf("start\n")
	// defer keyword postpones line execution but
	// it does not move it at the end (after main function is done), it simply 
	// checks if there are any "defered" lines and
	// it executes them before it "returns" !!!
	defer fmt.Printf("middle\n")
	defer fmt.Printf("end\n")
}

func getRequest()  {
	res, err := http.Get("http://www.google.com/robots.txt")
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

	robots, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("%s\n", robots)
}

func weirdBehavior()  {
	a := "start"
	// the reason why a will print "start" word is that 
	// keyword defer will assume all the values defined
	// before "defer" is actually used, since a ws set to "start"
	// a will print "start" :)
	defer fmt.Printf("Printing a: %v\n", string(a))
	a = "end"
}

func main() {
	// simpleFunc()
	// simpleFuncWithdeferKeyWord()
	// simpleFuncWithdeferKeyWordEverywhere()
	// getRequest()
	weirdBehavior()
}
author image

Jan Toth

I have been in DevOps related jobs for past 6 years dealing mainly with Kubernetes in AWS and on-premise as well. I spent quite a lot …

comments powered by Disqus