千家信息网

Go语言-panic和recover使用实战

发表于:2025-01-27 作者:千家信息网编辑
千家信息网最后更新 2025年01月27日,panic正常的函数执行流程将立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐层向上执行panic()流程,直到所属的goroutine中所
千家信息网最后更新 2025年01月27日Go语言-panic和recover使用实战

panic

正常的函数执行流程将立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐层向上执行panic()流程,直到所属的goroutine中所有正在执行的函数将被终止。错误信息将被报告,包括panic()的参数类型interface()我们可以看到,panic可以接收任意类型的数据
panic(404)
panic("network borken")
panic("Error("file not exists")

recover

recover函数用于终止错误处理流程。recover应该在defer关键字的函数中执行以有效截取错误处理流程

实例1

package mainimport (    "fmt")func main() {    defer func() {        if r := recover(); r != nil {            fmt.Println("detail:", r)        }    }()    fmt.Println("before painc")    panic("error1")    panic("error2")    fmt.Println("after panic")    return}

运行结果

before paincdetail: error1

实例2

package mainimport (    "fmt")func main() {    fmt.Println("before painc")    panic("error1")    panic("error2")    fmt.Println("after panic")    return}

运行结果

before paincpanic: error1goroutine 1 [running]:main.main()    /home/kenmy/go/src/github.com/shadowsocks/shadowsocks-go/sample-config/panic.go:17 +0xdd

实例3

package mainimport (    "fmt")func main() {    defer func() {        if r := recover(); r != nil {            fmt.Println("detail:", r)        }    }()    test()    fmt.Println("end")    return}func test() {    defer func() {        if r := recover(); r != nil {            fmt.Println("detail0:", r)        }    }()    fmt.Println("before painc")    panic("error1")    panic("error2")    fmt.Println("after panic")}

运行结果

before paincdetail0: error1end

实例4

package mainimport (    "fmt")func main() {    defer func() {        if r := recover(); r != nil {            fmt.Println("detail:", r)        }    }()    test()    fmt.Println("middle")    panic("error3")    fmt.Println("end")    return}func test() {    defer func() {        if r := recover(); r != nil {            fmt.Println("detail0:", r)        }    }()    fmt.Println("before painc")    panic("error1")    panic("error2")    fmt.Println("after panic")}

运行结果

before paincdetail0: error1middledetail: error3

实例5

package mainimport (    "fmt")func main() {    test()    fmt.Println("middle")    panic("error3")    fmt.Println("end")    return}func test() {    fmt.Println("before painc")    panic("error1")    panic("error2")    fmt.Println("after panic")}

运行结果:

before paincpanic: error1goroutine 1 [running]:main.test()    /home/kenmy/go/src/github.com/shadowsocks/shadowsocks-go/sample-config/panic.go:20 +0xddmain.main()    /home/kenmy/go/src/github.com/shadowsocks/shadowsocks-go/sample-config/panic.go:10 +0x26
0