go学习笔记异常处理

异常处理

没有结构化异常,使用panic抛出错误,recover捕获错误
package main

func test() {
    defer func() {
        if err := recover();err != nil {    //相当于php的错误异常处理的try
            println(err.(string))       //将interface转换成string类型
        }
    }()

    panic("panic error!")   //相当于php的throw
}

func main() {
    test()  //输出panic error!
}
由于panic,recover参数类型为interface{},因此可抛出任何类型对象
func panic(v interface{})   //不太理解
func recover() interface{}
延迟调用中引发的错误,可被后续延迟调用捕获,但仅最后一个错误可被捕获
package main

import "fmt"

func test() {
    defer func() {
        fmt.Println(recover())
    }()

    defer func() {
        panic("defer panic")
    }()

    panic("test panic")
}

func main() {
    test()  //输出结果为: defer panic
}
捕获函数recover只有在延迟调用内直接调用才会终止错误,否则总会返回nil,任何未捕获的错误都会沿调用栈向外传递
package main

import "fmt"

func test() {
    defer recover() //无效
    defer fmt.Println(recover())    //无效
    defer func() {
        //recover() //只有在此处才能捕获异常
        func() {
            println("defer inner")
            recover()   //无效
        }()
    }()

    panic("test panic")
}

func main() {
    test()
}
使用error.New和fmt.Errorf函数创建error接口的错误对象
package main

import "errors"

type error interface {
    Error() string
}

var ErrDivByZero = errors.New("division by zero")   //使用error.New创建error错误对象

func div(x, y int) (int, error) {
    if y == 0 { return 0, ErrDivByZero }
    return x / y, nil       //返回结果和异常
}

func main() {
    switch z, err := div(10, 0); err {  //初始化变量,然后再匹配异常err的信息
    case nil:
        println(z)
    case ErrDivByZero:
        panic(err)
    }
}
区分panic和error的两种方式,在包内部一般使用panic,对外api使用error返回值
坚持原创技术分享,您的支持将鼓励我继续创作!