用于抽象资源分配/释放的惯用 Go

Posted

技术标签:

【中文标题】用于抽象资源分配/释放的惯用 Go【英文标题】:Idiomatic Go for abstracting resource allocation/deallocation 【发布时间】:2015-07-28 11:10:36 【问题描述】:

是否有一种惯用的 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】:

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

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

【讨论】:

以上是关于用于抽象资源分配/释放的惯用 Go的主要内容,如果未能解决你的问题,请参考以下文章

2022-10-29:go语言中的defer能非常方便地处理资源释放问题,rust语言里如何实现defer功能呢?

将 self 与实例一起用于分配和释放 [重复]

golang之defer

Go 逃逸分析

使用代码来加载资源和释放资源

RAII&智能指针