Golang學習筆記_20——error
Golang學習筆記_21——Reader
Golang學習筆記_22——Reader示例
文章目錄
- error補充
- 1. 基本錯誤處理
- 2. 自定義錯誤
- 3. 錯誤類型判斷
- 3.1 類型斷言
- 3.2 類型選擇
- 4. panic && recover
- 源碼
error補充
1. 基本錯誤處理
在Go中,函數通常返回兩個值:一個是預期的結果,另一個是error
類型的值。
如果函數執行過程中發生錯誤,error
值將不為nil
。
func divide(a, b float64) (float64, error) {if b == 0 {return 0, errors.New("division by zero")}return a / b, nil
}func error_demo_1() {// 調用 divide 函數進行除法運算result, err := divide(10, 0)if err != nil {// 處理錯誤println("Error:", err)} else {// 輸出結果println("Result:", result)}
}
測試方法
func Test_error_demo_1(t *testing.T) {error_demo_1()
}
輸出結果
=== RUN Test_error_demo_1
Error: (0x105134bc8,0x1400009ef48)
--- PASS: Test_error_demo_1 (0.00s)
PASS
2. 自定義錯誤
自定義錯誤類型可以實現error接口,該接口僅包含一個Error方法,返回一個字符串。
// 自定義錯誤
type MyError2 struct {When stringwhat string
}func (e *MyError2) Error() string {return fmt.Sprintf("when: %s, what: %s", e.When, e.what)
}func testMyError() error {err := &MyError2{When: "now",what: "something wrong",}return err
}
測試方法
func Test_testMyError(t *testing.T) {if err := testMyError(); err != nil {fmt.Println(err)}
}
輸出結果
=== RUN Test_testMyError
when: now, what: something wrong
--- PASS: Test_testMyError (0.00s)
PASS
3. 錯誤類型判斷
3.1 類型斷言
// MyError2 是自定義錯誤類型func ErrorAssertDemo() error {err := &MyError2{When: "now",what: "something wrong",}return err
}func TestErrorAssertDemo() {err := ErrorAssertDemo()if specificErr := err.(*MyError2); specificErr != nil {fmt.Println("specificErr:", specificErr)} else {fmt.Println("normalErr:", err)}
}
測試方法
func Test_ErrorAssertDemo(t *testing.T) {TestErrorAssertDemo()
}
輸出結果
=== RUN Test_ErrorAssertDemo
specificErr: when: now, what: something wrong
--- PASS: Test_ErrorAssertDemo (0.00s)
PASS
3.2 類型選擇
// 錯誤類型選擇
// MyError2 是自定義錯誤類型
func ErrorTypeDemo1() error {return &MyError2{When: "now",what: "myError wrong",}
}func ErrorTypeDemo2() error {return errors.New("normal wrong")
}func switchErrorDemo(err error) {if err != nil {switch err1 := err.(type) {case *MyError2:fmt.Println("myError2:", err1)default:fmt.Println("normal:", err1)}}
}func TestErrorTypeDemo() {err1 := ErrorTypeDemo1()err2 := ErrorTypeDemo2()switchErrorDemo(err1)switchErrorDemo(err2)
}
測試方法
func Test_ErrorTypeDemo(t *testing.T) {TestErrorTypeDemo()
}
輸出結果
=== RUN Test_ErrorTypeDemo
myError2: when: now, what: myError wrong
normal: normal wrong
--- PASS: Test_ErrorTypeDemo (0.00s)
PASS
4. panic && recover
在Go中,panic
用于表示一個不可恢復的運行時錯誤。當panic
發生時,程序將停止正常執行,并開始逐級調用已注冊的延遲函數(deferred functions),隨后程序崩潰。
recover
是一個內置函數,用于從panic
中恢復。它只能在延遲函數中調用。在正常的執行路徑中調用recover
將返回nil
。
// panic 和 recover
func myPanic() {panic("error happened")
}func safeRecover() {defer func() {if err := recover(); err != nil {fmt.Println("recover:", err)}}()myPanic()
}
測試方法
func Test_safeRecover(t *testing.T) {safeRecover()fmt.Println("after recover")}
輸出結果
=== RUN Test_safeRecover
recover: error happened
after recover
--- PASS: Test_safeRecover (0.00s)
PASS
源碼
// error_demo_2.go 文件
package error_demoimport ("errors""fmt"
)func divide(a, b float64) (float64, error) {if b == 0 {return 0, errors.New("division by zero")}return a / b, nil
}func errorDemo1() {// 調用 divide 函數進行除法運算result, err := divide(10, 0)if err != nil {// 處理錯誤println("Error:", err)} else {// 輸出結果println("Result:", result)}
}// 自定義錯誤
type MyError2 struct {When stringwhat string
}func (e *MyError2) Error() string {return fmt.Sprintf("when: %s, what: %s", e.When, e.what)
}func testMyError() error {err := &MyError2{When: "now",what: "something wrong",}return err
}func ErrorAssertDemo() error {err := &MyError2{When: "now",what: "something wrong",}return err
}func TestErrorAssertDemo() {err := ErrorAssertDemo()if specificErr := err.(*MyError2); specificErr != nil {fmt.Println("specificErr:", specificErr)} else {fmt.Println("normalErr:", err)}
}// 類型選擇
func ErrorTypeDemo1() error {return &MyError2{When: "now",what: "myError wrong",}
}func ErrorTypeDemo2() error {return errors.New("normal wrong")
}func switchErrorDemo(err error) {if err != nil {switch err1 := err.(type) {case *MyError2:fmt.Println("myError2:", err1)default:fmt.Println("normal:", err1)}}
}func TestErrorTypeDemo() {err1 := ErrorTypeDemo1()err2 := ErrorTypeDemo2()switchErrorDemo(err1)switchErrorDemo(err2)
}// panic 和 recoverfunc myPanic() {panic("error happened")
}func safeRecover() {defer func() {if err := recover(); err != nil {fmt.Println("recover:", err)}}()myPanic()
}
// error_demo_2_test.go 文件
package error_demoimport ("fmt""testing"
)func Test_error_demo_1(t *testing.T) {errorDemo1()
}func Test_testMyError(t *testing.T) {if err := testMyError(); err != nil {fmt.Println(err)}
}func Test_ErrorAssertDemo(t *testing.T) {TestErrorAssertDemo()
}func Test_ErrorTypeDemo(t *testing.T) {TestErrorTypeDemo()
}func Test_safeRecover(t *testing.T) {safeRecover()fmt.Println("after recover")}