异常处理
异常是指程序在执行过程中发生的错误,会导臹程序终止。Go 语言提供了一种机制来处理运行时错误,这种机制被称为异常处理。
创建异常
Go 内置了一个 error
类型,用于表示异常。error
类型是一个接口类型,定义如下:
type error interface {
Error() string // Error 方法,返回异常信息
}
使用 errors
包的 New
函数可以创建一个异常:
package main
import (
"errors"
"fmt"
)
func main() {
err := errors.New("this is an error")
fmt.Println(err)
}
抛出异常
Go 语言没有提供 throw
关键字来抛出异常,而是使用 panic
函数来抛出异常。panic
函数接收一个任意类型的参数,通常是一个字符串,用于描述异常信息。
func handleError() {
panic(errors.New("this is an error"))
}
func main() {
fmt.Println("start")
handleError()
fmt.Println("end")
}
输出结果:
start
panic: this is an error
goroutine 1 [running]:
main.handleError()
/Users/jetzihan/Code/go/src/github.com/jetzihan/go-note/note/golang/error.go:8 +0x3b
main.main()
/Users/jetzihan/Code/go/src/github.com/jetzihan/go-note/note/golang/error.go:13 +0x2d
exit status 2
自定义异常
Panic 函数允许用户自定义异常。
func panic(v any)
即 panic 函数接收任意类型的参数,可以是任意类型的值。
package main
import (
"fmt"
)
func main() {
panic("this is an error")
}
倘若想要携带错误码等更多的信息,可以使用结构体。
package main
import (
"fmt"
)
type MyError struct {
Code int
Msg string
}
func handleError() {
e := MyError{Code: 100, Msg: "this is an error"}
panic(e)
}
func main() {
fmt.Println("start")
handleError()
fmt.Println("end")
}
输出结果:
start
panic: (*main.MyError) 0xc0000b2000
goroutine 1 [running]:
main.handleError()
/Users/jetzihan/Code/go/src/github.com/jetzihan/go-note/note/golang/error.go:10 +0x3b
main.main()
/Users/jetzihan/Code/go/src/github.com/jetzihan/go-note/note/golang/error.go:15 +0x2d
exit status 2
可以看到,输出的异常信息是 (*main.MyError) 0xc0000b2000
,这是因为 panic
函数只能接收字符串类型的参数,没有按照我们希望的方式输出异常信息。我们可以实现 error
接口来自定义异常。
package main
import (
"fmt"
)
type MyError struct {
Code int
Msg string
}
func (e MyError) Error() string {
return fmt.Sprintf("Code: %d, Msg: %s", e.Code, e.Msg)
}
func handleError() {
e := MyError{Code: 100, Msg: "this is an error"}
panic(e)
}
func main() {
fmt.Println("start")
handleError()
fmt.Println("end")
}
输出结果:
start
panic: Code: 100, Msg: this is an error
goroutine 1 [running]:
main.handleError()
/Users/jetzihan/Code/go/src/github.com/jetzihan/go-note/note/golang/error.go:10 +0x3b
main.main()
/Users/jetzihan/Code/go/src/github.com/jetzihan/go-note/note/golang/error.go:20 +0x2d
exit status 2
捕获异常
Go 语言提供了 recover
函数来捕获异常。recover
函数只能在 defer
函数中调用,用于捕获异常。
func recover() any
recover
函数返回一个 interface{}
类型的值,表示捕获的异常信息。如果没有异常被抛出,recover
函数返回 nil
。正确的做法是在 defer
函数中调用 recover
函数,然后判断返回值是否为 nil
,如果不为 nil
,则表示捕获到了异常。
package main
import (
"fmt"
)
func handleError() {
panic("this is an error")
}
func main() {
fmt.Println("start")
defer func() {
if err := recover(); err != nil {
fmt.Println("recover:", err)
}
}()
handleError()
fmt.Println("end")
}