Go语言defer简介
derfer
是Go语言中的关键字,用于定义延迟执行语句,defer
语句会将其后面跟随的语句进行延迟处理,在defer
归属的函数即将返回时,执行其后的语句。通常用于释放某些已经分配的资源,关闭文件流等。例如:
package main
import(
"os"
"fmt"
)
func main() {
f, _ := os.Open("./main.go")
defer f.Close()
// TODO: 读取文件或其他处理
}
多个defer怎么处理?
多个defer
语句,按defer
的逆序执行,也就是先被defer
的语句最后被执行,最后defer
的语句最先执行。例如:
package main
import "fmt"
func main() {
defer fmt.Println("A")
defer fmt.Println("B")
defer fmt.Println("C")
}
其运行结果为:
C
B
A
defer使用注意事项
defer常见错误1
package main
import (
"fmt"
"errors"
)
func handleError(err error) {
// 处理错误
fmt.Println(err)
}
func main() {
var err error
defer handleError(err)
// TODO: 处理某些可能发生错误的业务逻辑,此处直接赋值错误
err = errors.New("something error")
fmt.Prontln(err)
}
其运行结果为:
shomething error
<nil>
错误分析:handleError
函数中的err
永远为nil
,是因为Go中函数参数的传递是值传递,要想获取err
在程序后续运行中的值,需要传递err
的指针,正确的调用形式如下:
package main
import (
"fmt"
"errors"
)
func handleError(err *error) {
// 处理错误
fmt.Println(*err)
}
func main() {
var err error
defer handleError(&err)
// TODO: 处理某些可能发生错误的业务逻辑,此处直接赋值错误
err = errors.New("something error")
fmt.Prontln(err)
}
defer常见错误2
package main
import(
"fmt"
"errors"
)
func GetError(err *error) String() {
if err == nil || *err == nil {
return "no error message"
}
return err.Error()
}
func OutputErrorMessage(errMsg string) {
fmt.Println(errMsg)
}
func main() {
var err error
defer OutputErrorMessage( GetError(&err) )
// TODO: 处理某些可能发生错误的业务逻辑,此处直接赋值错误
err = errors.New("something error")
fmt.Prontln(err)
}
其运行结果为:
something error
no error message
错误分析:函数中参数如果是通过调用函数获取,会先执行函数,然后再进行传参。也就是GetError(&err)
会被先执行,此时err
为nil
,所以先获取到结果no error message
,然后传参给OutputErrorMessage
函数的errMsg
。正确的调用方式如下:
package main
import(
"fmt"
"errors"
)
func GetError(err *error) String() {
if err == nil || *err == nil {
return "no error message"
}
return err.Error()
}
func OutputErrorMessage(err *error) {
fmt.Println( GetError(err) )
}
func main() {
var err error
defer OutputErrorMessage(&err)
// TODO: 处理某些可能发生错误的业务逻辑,此处直接赋值错误
err = errors.New("something error")
fmt.Prontln(err)
}