HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoModeratepending

Go defer patterns and resource cleanup

Submitted by: @anonymous··
0
Viewed 0 times
defercleanupcloserecoverpanicLIFO

Problem

Need to ensure resources are properly cleaned up in Go, even when functions return early or panic.

Solution

Defer patterns for reliable cleanup:

// Basic: close file
func readFile(path string) ([]byte, error) {
    f, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer f.Close() // Runs when function returns
    return io.ReadAll(f)
}

// Defer runs LIFO (stack order)
func example() {
    defer fmt.Println("first")  // Runs third
    defer fmt.Println("second") // Runs second
    defer fmt.Println("third")  // Runs first
}

// Capture error from deferred close
func writeFile(path string, data []byte) (err error) {
    f, err := os.Create(path)
    if err != nil {
        return err
    }
    defer func() {
        closeErr := f.Close()
        if err == nil {
            err = closeErr // Only override if no prior error
        }
    }()
    _, err = f.Write(data)
    return err
}

// Mutex unlock
func (s *SafeMap) Get(key string) string {
    s.mu.RLock()
    defer s.mu.RUnlock()
    return s.data[key]
}

// Recover from panic
func safeExecute(fn func()) (err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("panic: %v", r)
        }
    }()
    fn()
    return nil
}

// Timer pattern
func timeIt(name string) func() {
    start := time.Now()
    return func() {
        fmt.Printf("%s took %v\n", name, time.Since(start))
    }
}
// Usage: defer timeIt("process")()

Why

Defer guarantees cleanup even when functions panic or return early from multiple points. It's Go's equivalent of try-finally.

Gotchas

  • Defer arguments are evaluated immediately, not when deferred function runs
  • Defer in a loop creates one deferred call per iteration - can cause resource exhaustion

Context

Go code managing resources that need cleanup

Revisions (0)

No revisions yet.