嵌入式Linux应用开发之异常处理

1、defer语句
defer 语句的用途是:含有 defer 语句的函数或类型方法,会在该函数或方法将要返回之前(return之前),调用另一个函数。所以,****我们可以在函数开始时,将一些容易忘记的结束操作用defer声明好,这样保证这些结束操作能在函数结束后正确执行。当defer要调用的函数有参数时,执行 defer 语句的时候,就会对延迟函数的实参进行求值。举例如下
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)} 当一个函数内多次调用 defer 时,go 会把 defer 调用放入到一个栈中,随后按照后进先出(last in first out, lifo)的顺序执行。
2、错误处理
2.1、error类型
在 go 中,错误一直是很常见的。错误用内建的 error 类型来表示。就像其他的内建类型(如 int、float64 等),错误值可以存储在变量里、作为函数的返回值等等。error类型定义如下:
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()返回的描述不是很详细,我们可以用下面的方法获取更详细的错误信息:
判断底层结构体类型(即实现error接口的结构体),使用结构体字段获取更多信息
判断底层结构体类型(即实现error接口的结构体),调用类型的方法获取更多信息
与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
fmt 包中的 errorf 函数会根据格式说明符,规定错误的格式,并返回一个符合该错误的字符串。示例:
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
有些情况,当程序发生异常时,无法继续运行。在这种情况下,我们会使用 panic 来终止程序。当函数发生 panic 时,它会终止运行,在执行完所有的defer延迟函数后,程序控制返回到该函数的调用方。这样的过程会一直持续下去,直到当前协程的所有函数都返回退出,然后程序会打印出panic信息,接着打印出堆栈跟踪(stack trace),最后程序终止。当程序发生 panic 时,使用 recover 可以重新获得对该程序的控制。 需要注意:
你应该尽可能地使用错误,而不是使用 panic 和 recover。只有当程序不能继续运行的时候,才应该使用 panic 和 recover 机制。
**必须在defer函数中直接调用recover**。在延迟函数内调用 recover,可以取到 panic 的错误信息,并且停止panic续发事件(panicking sequence),程序运行恢复正常。如果在延迟函数的外部调用 recover,就不能停止panic续发事件。
只有在相同的go协程中调用 recover 才管用。recover 不能恢复一个不同协程的 panic
使用示例
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, *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使用的模板,可供参考:


CFE汽车行业pogopin磁吸连接方案
常见十几种电容分类详细介绍
鲁大师发布Q3季度安卓手机性能榜,两款游戏新机拿下前两名
迪士尼Imagineering能把Groot机器人带进现实吗
信号链基础知识#29:数字接口—单端接口与差动接口的对比
嵌入式Linux应用开发之异常处理
看到科技发布“三镜头” 3D/全景相机,售价2499元,支持4K拍摄
为windows XP的USB设备添加“只读属性”方法及图解
中美 SaaS 领域的差别
科学家创造出脑打字系统
超小型位移传感器 LVDT 在这些行业派上用场及使用注意事项
Google新型人工智能透明度工具的优缺点
半导体工程师春节如何向亲戚描述工作
[组图]4x0换系统软件教程
为什么是恩智浦获得高通的青睐?
湘能华磊光电的LED外延层生长方法专利揭秘
器官芯片汇总
荣耀畅玩8C续航到底怎么样
博通公司端至端解决方案助力家庭联网发展
“TPY-X”雷达的分布式数字架构设计方案