Skip to content

Instantly share code, notes, and snippets.

@thelissimus
Last active April 16, 2024 11:51
Show Gist options
  • Save thelissimus/2d8815364d27d7b1116999df1775c61e to your computer and use it in GitHub Desktop.
Save thelissimus/2d8815364d27d7b1116999df1775c61e to your computer and use it in GitHub Desktop.
Better resource management in Go using "Bracket pattern".
package main
import (
"io/fs"
"os"
)
// Manual
func bracket[R any](acquire func() (R, error), release func(R) error, use func(R) error) error {
r, err := acquire()
if err != nil {
return err
}
if err = use(r); err != nil {
if cerr := release(r); cerr != nil {
return cerr
}
return err
}
return release(r)
}
// Semi auto
type Closer interface {
Close() error
}
func withResource[R Closer](acquire func() (R, error), use func(R) error) error {
return bracket(
acquire,
func(r R) error { return r.Close() },
use,
)
}
// Full auto
func withFile(filepath string, flag int, mode fs.FileMode, use func(*os.File) error) error {
return withResource(func() (*os.File, error) { return os.OpenFile(filepath, flag, mode) }, use)
}
func main() {
withFile("file.txt", os.O_CREATE, fs.ModeAppend, func(f *os.File) error {
_, err := f.Write([]byte("hey!"))
return err
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment