简体   繁体   English

习惯用法Go,用于抽象资源分配/取消分配

[英]Idiomatic Go for abstracting resource allocation/deallocation

Is there an idiomatic Go way for abstracting resource allocation/deallocation? 是否有惯用的Go方法来抽象化资源分配/取消分配? My initial guess is to abstract the allocation/deallocation in a higher-order function: 我最初的猜测是在更高阶的函数中抽象分配/取消分配:

func withResource(f func(Resource)error) error {
    // allocate resource
    // defer free resource
    return f(resource)
}

However, this line of thinking is borrowed directly from the functional paradigm and doesn't seem to align well with Go's largely imperative nature. 但是,这种思路是直接从功能范式中借用的,似乎与Go的主要命令性质并不完全一致。

As a concrete example, running a daemon for the duration of a block of code is a recurring theme in my current project, so I've created a withDaemon function to abstract the commonality: 作为一个具体示例,在我的当前项目中,经常在一个代码块的持续时间内运行守护程序是一个重复出现的主题,因此,我创建了一个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)
}

I think that the idiomatic way would be to create a Daemon type, and to just use defer in the caller: 我认为惯用的方法是创建一个Daemon类型,并只在调用方中使用defer:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM