1、defer语句

deferdeferdefer
func printA(a int) {  
    fmt.Println("value of a in deferred function", a)
}
func main() {  
    a := 5
    defer printA(a) //此时a=5,所以实际传到printA中的参数值为5,输出为5
    a = 10
    fmt.Println("value of a before deferred function call", a)
}
deferdefer

2、错误处理

2.1、error类型

errorintfloat64error
type error interface { //是一个接口,实现该接口的类型都可以当作错误类型
    Error() string
}

使用示例:

func main() {  
    f, err := os.Open("/test.txt")
    if err != nil {//error类型
        fmt.Println(err)
        return
    }
    fmt.Println(f.Name(), "opened successfully")//println会自动调用Error()输出错误信息
}

2.2、提取错误信息的方法

Error()返回的描述不是很详细,我们可以用下面的方法获取更详细的错误信息:

  1. 判断底层结构体类型(即实现error接口的结构体),使用结构体字段获取更多信息
  2. 判断底层结构体类型(即实现error接口的结构体),调用类型的方法获取更多信息
  3. 与error类型变量直接比较
func main() {  
    files, err := filepath.Glob("[")
    if error != nil && err == filepath.ErrBadPattern {//比较,判断是不是某个指定的错误类型
        fmt.Println(err)
        return
    }
    fmt.Println("matched files", files)
}

2.3、fmt.Errorf

fmtErrorf
func circleArea(radius float64) (float64, error) {  
    if radius < 0 {
        //返回错误类型
        return 0, fmt.Errorf("Area calculation failed, radius %0.2f is less than zero", radius)
    }
    return math.Pi * radius * radius, nil
}

func main() {  
    radius := -20.0
    area, err := circleArea(radius)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("Area of circle %0.2f", area)
}

3 panic和recover

panicrecover
deferrecoverrecoverpanicrecoverrecover

使用示例

func recoverName() {  
    if r := recover(); r!= nil {//恢复程序运行
        fmt.Println("recovered from ", r)
        debug.PrintStack()//打印panic异常的堆栈信息
    }
}

func fullName(firstName *string, lastName *string) {  
    defer recoverName() //延迟函数
    if firstName == nil {
        panic("runtime error: first name cannot be nil")//触发程序异常
    }
    if lastName == nil {
        panic("runtime error: last name cannot be nil")
    }
    fmt.Printf("%s %s\n", *firstName, *lastName)
    fmt.Println("returned normally from fullName")
}

func main() {  
    defer fmt.Println("deferred call in main")
    firstName := "Elon"
    fullName(&firstName, nil)
    fmt.Println("returned normally from main")
}

一个通用的recover defer使用的模板,可供参考:

func foo() (err error) {
    defer func() {
        if r := recover(); r != nil {
            switch x := r.(type) {
            case string:
                err = errors.New(x)
            case error:
                err = x
            default:
                err = fmt.Errorf("Unknown panic: %v", r)
            }
        }
    }()

    panic("TODO")
}
嵌入式物联网需要学的东西真的非常多,千万不要学错了路线和内容,导致工资要不上去!
分享大家一个资料包,差不多150多G。里面学习内容、面经、项目都比较新也比较全!点击这里找小助理0元领取:
转载自:嵌入式应用研究院
文章来源于golang极速嵌入式Linux应用开发(五)-异常处理
原文链接:https://mp.weixin.qq.com/s/_cLX3SiH5y7gNUBANomZ4Q