gpt4 book ai didi

go - 初始化多个资源并管理它们的生命周期

转载 作者:IT王子 更新时间:2023-10-29 02:10:02 24 4
gpt4 key购买 nike

假设您必须初始化一系列资源才能执行某些操作,通常一个初始化依赖于下一个初始化。例如,您需要启动浏览器、打开浏览器窗口、打开选项卡、将该选项卡导航到网站。在操作结束时,您想关闭或拆除您已初始化的所有资源。

让我们看看这个天真的代码:

func main() {
window, err := NewWindow()
if err != nil {
panic(err)
}
defer window.Close()

tab, err := NewTab(window)
if err != nil {
panic(err)
}
defer tab.Close()

NavigateToSite(tab)
}

(当然,这段代码非常简单,所以有人可能会问为什么要重构它,所以记住这是为了示例,实际的初始化链可能更长更复杂。)

然后假设我想分解初始化,注意到我代码中的实际逻辑根本不需要 window。什么是惯用的方式来做到这一点?目前我能想到的是:

func main() {
rs, err := NewMyResource()
if err != nil {
panic(err)
}
defer rs.Close()

NavigateToSite(rs.Tab)
}

struct MyResource {
Window *window;
Tab *tab;
}

func NewMyResource() (*MyResource, error) {
rs := &MyResource{}

window, err := CreateWindow()
if err != nil {
rs.Close()
return nil, err
}
rs.Window = window

tab, err := CreateTab()
if err != nil {
rs.Close()
return nil, err
}
rs.Tab := tab

return rs, nil
}

func (rs MyResource) Close() {
if rs.Window != nil {
rs.Window.Close()
}

if rs.Tab != nil {
rs.Tab.Close()
}
}

最佳答案

一个可能的替代方案(不一定更好,取决于上下文)可能是返回一个闭包:

func NewMyResource() (tab Tab, closer func(), err error) {
var window Window
window, err = NewWindow()
if err != nil {
return
}

tab, err = NewTab(window)
if err != nil {
return
}
closer = func() {
tab.Close()
window.Close()
}
return
}

像这样使用它:

tab, cl, err := NewMyResource()
if err != nil {
panic(err)
}
defer cl()

我通常会选择基于结构的解决方案,但有时新类型有点矫枉过正,返回函数更容易。

关于go - 初始化多个资源并管理它们的生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49547745/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com