惯用于抽象资源分配/解除分配

时间:2015-05-16 16:13:58

标签: error-handling go resources idioms

是否有一种习惯性的Go方式来抽象资源分配/解除分配?我最初的猜测是在高阶函数中抽象分配/释放:

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)
}

1 个答案:

答案 0 :(得分:6)

我认为惯用的方法是创建一个守护进程类型,并在调用者中使用defer:

d := NewDaemon(...)
defer d.Stop()
doWhatever()