1. 程式人生 > >2.14 異常處理3:自定義異常

2.14 異常處理3:自定義異常

自定義異常概述

  • 系統提供的異常類error無所不包但控制的粒度很粗糙
  • 如果想要進行很精細化的報錯和處理錯誤,就需要用到自定義異常
  • 我們只要實現error介面中的Error() string方法,就可以自定義異常了
  • 自定義的異常與系統異常無二,同樣可以panic,同樣可以辯證互斥地返回【結果錯誤對】

自定義異常

  • 下面的例子定義了一個【非法引數異常】
  • 在這個自定義的結構體中,封裝了異常提示資訊、發生時間、造成異常的使用者三個屬性
  • 這樣的異常在報出和處理時,無疑具有更直觀更豐富的參考價值
//自定義【非法引數異常】,封裝異常提示資訊、發生時間、造成異常的使用者三個屬性
type InvalidArgError struct
{ info string when time.Time user string } //實現系統的異常介面 func (iae *InvalidArgError)Error() string{ return fmt.Sprintln(iae.info,iae.when,iae.user) } //模仿SDK,提供一個建立異常物件的工廠方法,自動記錄發生異常的時間和使用者 func NewInvalidArgError(info string) *InvalidArgError { iaePtr := new(InvalidArgError) iaePtr.info = info iaePtr.when = time.Now() iaePtr.user = "bill"
return iaePtr }

以錯誤的形式返回異常資訊

//如果引數為負數時,返回一個自定義的異常
func getCircleAreaIII(radius float32)(ret float32,err interface{}) {
    if radius < 0{
        //err = errors.New("傻鳥,半徑不能為負")
        err = NewInvalidArgError("傻鳥,半徑不能為負")
        return
    }
    ret = 3.14 * radius * radius
    return
}

//返回自定義異常
func demo41() { ret, err := getCircleAreaIII(-5) if err != nil { //fmt.Println(err) fmt.Sprintln(err) } else { fmt.Println("ret=", ret) } } func main() { demo41() }

以恐慌的形式報異常並處理

//半徑為負數的情況下以恐慌形式報出異常
func getCircleAreaIV(radius float32)(ret float32) {
    if radius < 0{
        panic(NewInvalidArgError("傻吊半徑不能為負數"))
    }
    ret = 3.14 * radius * radius
    return
}

//處理丟擲的恐慌
func demo42() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Println(err)
        }
    }()
    getCircleAreaIV(-5)
}

func main() {
    demo42()
}