英文:
go - Cleanup resources only when the function is about to return an error
问题
假设我有一个函数,首先创建一个目录,然后执行一些其他操作,代码如下:
{
err := os.Mkdir(path, os.ModePerm)
...
err = doSomething()
if err != nil {
return nil, err
}
err = doSomethingElse()
if err != nil {
return nil, err
}
return path, nil
}
现在,我希望在发生错误的情况下,函数能够删除它创建的目录。有什么比较简洁的方法可以实现这个需求?
一种方法是在每个 if
分支中调用 os.RemoveAll
,但这不是一个很好的解决方案。另一种方法是使用 defer
语句,但这样也会在没有错误的情况下执行。
英文:
Suppose I have a function that starts by creating a directory, and then doing some more stuff, like this:
{
err := os.Mkdir(path, os.ModePerm)
...
err = doSomething()
if err != nil {
return nil, err
}
err = doSomethingElse()
if err != nil {
return nil, err
}
return path, nil
}
Now, I want the function to delete the directory it created in all of those cases where an error occured. What is the cleanest way to do this?
One way would be to call os.RemoveAll
in every if
branch, but that's not a very nice solution. Another way would be to use a defer
statement, but that would also get executed in the case where there was no error.
答案1
得分: 3
是的,延迟函数始终会被执行,但是否删除目录完全取决于你。
使用延迟函数并检查错误。如果没有错误,则不要删除目录。为了使其工作,使用命名返回参数,例如:
func foo() (result resultType, err error) {
path := "some folder"
defer func() {
if err != nil { // 这是结果中的 err
if err2 := os.RemoveAll(path); err2 != nil {
// 处理 err2
}
}
}()
err := os.Mkdir(path, os.ModePerm)
...
}
请注意,如果有显式的 return
语句,例如:
return path, errors.New("bar")
上述 return
语句首先将值分配给 result
和 err
,因此在延迟函数中可以获取/查看这些值。
参考链接:https://stackoverflow.com/questions/33167282/how-to-return-a-value-in-a-go-function-that-panics/33167433#33167433
英文:
Yes, a deferred function will always be executed, but whether it deletes the directory depends entirely on you.
Use a deferred function, and check the error. If there was no error, do not delete the directory. For this to work, use named result parameters, e.g.:
func foo() (result resultType, err error) {
path := "some folder"
defer func() {
if err != nil { // This is the result err
if err2 := os.RemoveAll(path); err2 != nil {
// handle err2
}
}
}()
err := os.Mkdir(path, os.ModePerm)
...
}
Note that if there is an explicit return
stament like:
return path, errors.New("bar")
The above return
statement first assigns the values to result
and err
, so in deferred functions you can get / see those values.
See related: https://stackoverflow.com/questions/33167282/how-to-return-a-value-in-a-go-function-that-panics/33167433#33167433
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论