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,如数组越界