Go学习之资源管理与异常处理
def调用
保证调用在函数结束时发生
func writeFile(filename string) { file, e := os.Create(filename) if e != nil { panic(e) } defer file.Close() writer := bufio.NewWriter(file) defer writer.Flush() f := fib.Fibonacci() for i := 0; i < 20; i++ { fmt.Fprintln(writer, f()) } }
参数在defer语句时计算
defer列表为后进先出
何时使用defer调用
- Open/Close
- Lock/Unlock
- PrintHeader/PrintFooter
出错处理
包装函数
type appHandler func(writer http.ResponseWriter, request *http.Request) error func errWrapper(handler appHandler) func(writer http.ResponseWriter, request *http.Request) { return func(writer http.ResponseWriter, request *http.Request) { err := handler(writer, request) if err != nil { log.Warn("Error handling request:%s", err.Error()) code := http.StatusOK switch { case os.IsNotExist(err): code = http.StatusNotFound case os.IsPermission(err): code = http.StatusForbidden default: code = http.StatusInternalServerError } http.Error(writer, http.StatusText(code), code) } }}
panic
- 停止当前函数执行
- 一直往上返回,执行每一层的defer
- 如果没有遇到recover,程序退出
recover
- 仅在defer调用中使用
- 获取panic的值
- 如果无法处理,可重新panic
error vs panic
- 意料之中的:使用error,如文件打不开
- 意料之外的:使用panic,如数组越界