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"
)
网友评论