GO学习笔记(14) - 错误处理

49 阅读1分钟

Defer

  • 确保在函数结束时对资源进行相关操作
  • 先进后出的原则,多条语句越靠近尾部越先执行
	func readWriter(filename string)  {
	file,err := os.Create(filename)
	if err != nil{
		panic(err)
	}
	//关闭资源
	defer file.Close()

	writer := bufio.NewWriter(file)
	defer  writer.Flush()

	f :=  fibonacci.Fibonacci()
	for i := 0;i<20;i++  {
        //倒数打印
		defer fmt.Println(i) 
		if i >=19 {
			break
		}
		fmt.Fprintln(writer,f())
	}
}

Panic vs Recover

Panic

  • 异常抛出,停止函数执行
  • 一直向上返回,执行每一层的defer
  • 如查没有遇到recover,程序退出

Recover

  • 仅在defer调用中使用
  • 获取panic的值,如无法处理,则重新panic

常规错误处理的方法

	file,err := os.Create(filename)
	if err != nil{
		if pathError, ok := err.(*os.PathError); !ok{
			panic(err)
		}else {
			fmt.Printf("%s %s %s  \n",
				pathError.Op,
				pathError.Path,
				pathError.Err)
		}
		return
	}

含Recover的例子

package main

import (
	"fmt"
)

func tryRecovery()  {
	defer func() {
		r := recover()
		if err,ok := r.(error); ok {
			fmt.Println("Error occured:",err)
		}else{
			panic(r)
		}
	}()

	//panic(errors.New("This is an error!"))
	a := 5/0
	fmt.Println(a)
}

func main() {
	tryRecovery()
}

自定义错误

  • 定义
type UserError string


func (e UserError) Error() string{
	return e.Message()
}

func (e UserError) Message() string{
	return fmt.Sprintf("%s", e)
	//return  string(e)
}
  • 错误
	if strings.Index(request.URL.Path,PREFIX) !=0{
		return error2.UserError("path must with "+prefix)
	}
  • 判断是否为UserError错误
if err != nil{
  if userError,ok := err.(userError); ok {
   	http.Error(writer,userError.Message(),http.StatusBadRequest)
   }else{ 
        //TODO:...
   }
...

go语言

package tests

import (
	"math"
	"testing"
)