[Go] Defer keyword

defermake sure the operation will be executed at the end of a function.

func loadChampions() ([]champion, error) {
	file, err := os.Open("tft_champions.json")
	if err != nil {
		return nil, err
	}

	defer file.Close()

	var champions []champion
	for {
		if err := json.NewDecoder(file).Decode(&champions); err == io.EOF {
			break
		} else if err != nil {
			return nil, err
		}
	}

	return champions, nil
}

 

Notice that even we write defer file.Close() after os.Open, it doesn't mean it will close the file right away, file will be close by the end of the function.

 

Key Points about defer:

  • Resource Management: It's a best practice to use defer for closing files, network connections, or releasing other resources. This pattern helps prevent resource leaks, which can lead to performance issues or crashes due to exhausted resources.

  • Order of Execution: If multiple defer statements are called within the same function, they are executed in the reverse order they were deferred. This LIFO (Last In, First Out) execution order is particularly useful when the order of operations for cleanup is important.

  • Error Handling and Cleanup: In functions with complex error handling and multiple return points, defer ensures that cleanup actions are performed without needing to duplicate cleanup code before each return statement.

  • Deferred Function Arguments: The arguments of a deferred function are evaluated when the defer statement is executed, not when the deferred function is actually called. This is an important distinction when deferring a call with arguments that may change later in the function.

  • Panic Recovery: defer can also be used in conjunction with recovery from panics (unexpected errors), allowing a program to recover from an error state gracefully or to perform necessary cleanup before crashing.

posted @ 2024-02-06 03:22  Zhentiw  阅读(3)  评论(0编辑  收藏  举报