异常处理
异常是指程序在执行过程中发生的错误,会导臹程序终止。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() anyrecover 函数返回一个 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")
}