# Defer

This Go code illustrates the use of `defer` statements to ensure that certain actions, like closing a file, are performed even if an error occurs. Let's go through the code with inline comments and explanations:

```go
// Importing necessary packages.
import (
	"fmt"
	"os"
)

// The main function, where the execution of the program begins.
func main() {
	// Creating a file and deferring the closing of the file until the surrounding function returns.
	f := createFile("/tmp/defer.txt")
	defer closeFile(f)

	// Writing data to the file.
	writeFile(f)
}

// createFile function creates a file and returns a pointer to the os.File.
func createFile(p string) *os.File {
	fmt.Println("creating")
	// Attempting to create the file.
	f, err := os.Create(p)
	if err != nil {
		// If an error occurs during file creation, the program panics.
		panic(err)
	}
	return f
}

// writeFile function writes data to the provided os.File.
func writeFile(f *os.File) {
	fmt.Println("writing")
	// Writing the data to the file.
	fmt.Fprintln(f, "data")
}

// closeFile function closes the provided os.File, handling errors.
func closeFile(f *os.File) {
	fmt.Println("closing")
	// Closing the file and checking for errors.
	err := f.Close()

	// Handling errors if the file cannot be closed successfully.
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}
```

#### Output

```
creating
panic: open /tmp/defer.txt: The system cannot find the path specified.

goroutine 1 [running]:
main.createFile({0x622f83, 0xe})
       ..:/...../..../..../defer.go:19 +0x93
main.main()
       ..:/...../..../..../defer.go:10 +0x2b
exit status 2
```

Explanation:

1. **`createFile(p string) *os.File`:**
   * This function creates a file at the specified path `p`.
   * If an error occurs during file creation, the function panics with the error message.
   * The created file is returned as a pointer to `os.File`.
2. **`writeFile(f *os.File)`:**
   * This function writes the string "data" to the provided file (`os.File`).
3. **`closeFile(f *os.File)`:**
   * This function closes the provided file (`os.File`).
   * If an error occurs during file closing, it prints an error message to `os.Stderr` and exits the program.
4. **`defer closeFile(f)`:**
   * The `defer` statement ensures that the `closeFile` function is called when the surrounding function (`main` in this case) returns, regardless of whether it returns normally or panics.
   * In this example, it ensures that the file is closed even if an error occurs during the execution of `main`.

Using `defer` is a convenient way to ensure that cleanup actions are performed, especially when dealing with resources like files, to avoid resource leaks.
