Go

Lesson 08

Defer and resource cleanup

Use defer close to make cleanup follow resource acquisition and cover every return path.

Good Code

reviews/importer.go
func ImportReviews(path string) error {
    file, err := os.Open(path)
    if err != nil {
        return err
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        if err := importLine(scanner.Text()); err != nil {
            return err
        }
    }

    return scanner.Err()
}

Bad Code

reviews/importer.go
func ImportReviews(path string) error {
    file, err := os.Open(path)
    if err != nil {
        return err
    }

    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        if err := importLine(scanner.Text()); err != nil {
            return err
        }
    }

    file.Close()
    return scanner.Err()
}

Review Notes

What to review

Good Code

The good version defers cleanup immediately after opening the file, so early returns still release the resource.

Bad Code

The bad version closes only on the happy path. If importing a line fails, the file handle leaks until the process cleans it up.

Takeaways

  • Cleanup should sit close to acquisition so reviewers can see every path releases the resource.