Hacker News .hnnew | past | comments | ask | show | jobs | submitlogin

RAII is superior, but there's also another go pattern for that which reads better than your two alternatives sometimes:

    // You _must_ 'defer closeFunc()' (with closeFunc being the second return value) after this function,
    // even if this function returns an error.
    // You do not need to call File.Close() on the returned file, only closeFunc()
    func openFileAndPeakHeader(path string) (*os.File, func() error, error) {
        closeF := func() error { return nil }
        f, err := os.Open(path)
        if err != nil {
            return nil, closeF, err
        }
        closeF = f.Close
        // ...
        if _, err := f.Read(data); err != nil {
            return nil, closeF, err
        }
        return f, closeF, nil
    }
Unfortunately, it relies on someone reading docs for them to determine that this isn't an Either<(File, func), error>, but rather an Either<File, (func, error)>, but that's how go works anyways. You have to read doc comments to know what types an 'error' might be, you have to read docs to know if return values are Either or not (i.e. file.Read returns n, err, and both are meaningful, not just one of them).

It's not good, but I think it's better in some cases than the options you presented.



Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: