error
接口声明如下:
type error interface {
Error() string
}
创建error
err:=errors.New(“”)//返回的是其返回的error类型值的字符串表现形式
func New(text string) error {
return &errorString{text}
}
err2:=fmt.Errorf(“%s\n”,”A Error”)
//不会在标准输出上打印这个生成的字符串,而是用它初始化一个error类型的值,并作为该函数的结果值
//反馈给调用方
func Errorf(format string, a ...interface{}) error {
return errors.New(Sprintf(format, a...))
}
panic
panic函数被用于停止当前的控制流程(Groutine)的执行并报告一个运行时恐慌。它可以接受一个任意类型的参数。然而这个参数通常是一个string类型值或者error类型值。
panic(errors.New("A error"))
recover
运行时恐慌一旦引发就会向调用方法传递直至程序崩溃。这当然不是我们想碰到了,因为谁也无法保证程序不会发生任何运行时问题。不过,Go语言为我们提供了专用于”拦截”运行时恐慌的函数–recover。
不过,单靠这个内键函数不足以“拦截”恐慌。因为运行时恐慌使程序失去了流程控制权,无法让代码在恐慌之后运行。但一个例外:defer语句
defer func() {
if r:=recover();r!=nil{
fmt.Printf("Recover panice %s\n",r)
}
}()
网上的一个try/catch
package main
import (
"reflect"
)
type TryCatch struct {
errChan chan interface{}
catches map[reflect.Type]func(err error)
defaultCatch func(err error)
}
func (t TryCatch) Try(block func()) TryCatch {
t.errChan = make(chan interface{})
t.catches = map[reflect.Type]func(err error){}
t.defaultCatch = func(err error) {}
go func() {
defer func() {
t.errChan <- recover()
}()
block()
}()
return t
}
func (t TryCatch) CatchAll(block func(err error)) TryCatch {
t.defaultCatch = block
return t
}
func (t TryCatch) Catch(e error, block func(err error)) TryCatch {
errorType := reflect.TypeOf(e)
t.catches[errorType] = block
return t
}
func (t TryCatch) Finally(block func()) TryCatch {
err := <-t.errChan
if err != nil {
catch := t.catches[reflect.TypeOf(err)]
if catch != nil {
catch(err.(error))
} else {
t.defaultCatch(err.(error))
}
}
block()
return t
}
type MyError struct {
error
}
func main() {
TryCatch{}.Try(func() {
println("do something buggy")
panic(MyError{})
}).Catch(MyError{}, func(err error) {
println("catch MyError")
}).CatchAll(func(err error) {
println("catch error")
}).Finally(func() {
println("finally do something")
})
println("done")
}