大多数清除功能,特别是与IO操作相关的功能,都会返回error
,通常,我们更愿意defer
执行它们,以防万一我们在调用时不忘调用它们用获得的资源完成。例如,在代码中的某些时候,我们可能会编写如下代码:
var r *SomeResource
var err error
if r, err = Open(/* parameters */); err != nil {
return nil, err
}
defer r.Close() // This might return an error
如果Close
函数返回错误,它将被忽略。我们如何才能从这样的函数中轻轻地处理返回的error
?
答案 0 :(得分:6)
像这样将defer
与func() {}()
一起使用。
var r *SomeResource
var err error
if r, err = Open(/* parameters */); err != nil {
return nil, err
}
defer func() {
if err := r.Close(); err != nil {
fmt.Printf("ERROR: %v", err)
}
}()
答案 1 :(得分:3)
错误地正常失败。报告第一个错误。不要覆盖以前的错误。例如,
package main
import (
"fmt"
"os"
)
func demo() (name string, err error) {
filename := `test.file`
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer func() {
e := f.Close()
if e != nil {
if err == nil {
err = e
}
}
}()
// do someting with the file
name = f.Name()
fi, err := f.Stat()
if err != nil {
return name, err
}
if fi.Size() == 0 {
err = fmt.Errorf("%s: empty file", filename)
return name, err
}
return name, err
}
func main() {
name, err := demo()
fmt.Println(name, err)
}
答案 2 :(得分:-1)
我们可以通过以下方式处理此问题:
方式1:
func myFn() error {
var err error
if r, err = Open(/* parameters */); err != nil {
return nil, err
}
defer func() {
if cErr = r.Close(); cErr != nil {
err = cErr
}
}()
return err
}
方式2:
func myFn() error {
var err error
if r, err = Open(/* parameters */); err != nil {
return nil, err
}
defer func() {
if cErr = r.Close(); cErr != nil {
// we can log the error
// or
// whatever we want to do
}
}()
return err
}
我也在这个主题上找到了一个不错的博客,我的意思是当defer func返回错误时处理错误。在这里https://blog.learngoprogramming.com/5-gotchas-of-defer-in-go-golang-part-iii-36a1ab3d6ef1中检查。