用于抽象资源的惯用 Go allocation/deallocation
Idiomatic Go for abstracting resource allocation/deallocation
是否有一种惯用的 Go 方法来抽象资源 allocation/deallocation?我最初的猜测是将 allocation/deallocation 抽象为高阶函数:
func withResource(f func(Resource)error) error {
// allocate resource
// defer free resource
return f(resource)
}
然而,这种思路是直接从函数式范式中借鉴的,似乎与 Go 的命令式本质不太吻合。
举个具体的例子,运行 一个代码块持续时间的守护进程是我当前项目中反复出现的主题,因此我创建了一个 withDaemon
函数来抽象通用性:
func withDaemon(
cmd *exec.Cmd,
f func(io.ReadCloser, io.ReadCloser, io.WriteCloser) error,
) error {
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("couldn't get stdout: %v", err)
}
stderr, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("couldn't get stderr: %v", err)
}
stdin, err := cmd.StdinPipe()
if err != nil {
return fmt.Errorf("couldn't get stdin: %v", err)
}
if err := cmd.Start(); err != nil {
return fmt.Errorf("failed to start: %v", err)
}
defer func() {
cmd.Process.Kill()
cmd.Wait()
}
return f(stdout, stderr, stdin)
}
我认为惯用的方法是创建一个守护进程类型,并在调用者中使用延迟:
d := NewDaemon(...)
defer d.Stop()
doWhatever()
是否有一种惯用的 Go 方法来抽象资源 allocation/deallocation?我最初的猜测是将 allocation/deallocation 抽象为高阶函数:
func withResource(f func(Resource)error) error {
// allocate resource
// defer free resource
return f(resource)
}
然而,这种思路是直接从函数式范式中借鉴的,似乎与 Go 的命令式本质不太吻合。
举个具体的例子,运行 一个代码块持续时间的守护进程是我当前项目中反复出现的主题,因此我创建了一个 withDaemon
函数来抽象通用性:
func withDaemon(
cmd *exec.Cmd,
f func(io.ReadCloser, io.ReadCloser, io.WriteCloser) error,
) error {
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("couldn't get stdout: %v", err)
}
stderr, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("couldn't get stderr: %v", err)
}
stdin, err := cmd.StdinPipe()
if err != nil {
return fmt.Errorf("couldn't get stdin: %v", err)
}
if err := cmd.Start(); err != nil {
return fmt.Errorf("failed to start: %v", err)
}
defer func() {
cmd.Process.Kill()
cmd.Wait()
}
return f(stdout, stderr, stdin)
}
我认为惯用的方法是创建一个守护进程类型,并在调用者中使用延迟:
d := NewDaemon(...)
defer d.Stop()
doWhatever()