zoukankan      html  css  js  c++  java
  • Go中的异常处理

    1. errors包

    Go 有一个预先定义的 error 接口类型 :

    type error interface {
    	Error() string
    }
    

    错误值用来表示异常状态。Go也提供了一个包:errors,errors 包中有一个 errorString 结构体实现了 error 接口 。任何时候当你需要一个新的错误类型,都可以用 errors包的 errors.New 函数接收合适的错误信息来创建 :

    err := errors.New("so.this is a error test")
    

    2. 运行时异常和panic

    我们在代码段中定义了一个error,这个error我们可以处理也可以不处理,它并不会影响程序继续往下执行;但是如果在程序中定义了一个panic,那程序是一定不会往下执行。

    panic所定义的异常,是在程序运行到这里才触发,所以属于运行时异常。

    	fmt.Print("start....")
    	panic("an error occured: stopping")
    	fmt.Print("end")
    

    输出错误:

    start....panic: an error occured: stopping
    
    goroutine 1 [running]:
    main.main()
    	D:/workspace/go/demo/testError.go:11 +0x9d
    
    

    另外,如果panic函数遇到了defer延迟函数,在defer函数中触发了panic函数异常,会将该异常一直往上携带,一直输送到这个协程的起点:

    package main
    
    import (
    	"fmt"
    )
    
    func defer1()  {
    	panic("an error occured: stopping")
    	fmt.Println("defer1")
    }
    
    func defer2()  {
    	defer1()
    	fmt.Println("defer2")
    }
    
    func main() {
    	fmt.Println("start....")
    	defer defer2()
    	fmt.Println("end")
    
    }
    
    

    输出如下:

    start....
    end
    panic: an error occured: stopping
    
    goroutine 1 [running]:
    main.defer1(...)
    	D:/workspace/go/demo/testError.go:8
    main.defer2()
    	D:/workspace/go/demo/testError.go:13 +0x41
    main.main()
    	D:/workspace/go/demo/testError.go:22 +0xf7
    

    可以看到异常信息一直被带到了main函数中。

    那么既然有抛出异常,自然也会有异常捕获,recover就是这样的一个函数。

    3. recover

    正如名字一样,这个(recover)内建函数被用于从 panic 或 错误场景中恢复 。recover的使用方式是:必须的在defer修饰的方法中使用,不然不生效。原因你应该懂:panic抛出异常,defer具备延迟处理功能,所以最后这种兜底的活只能defer来做。

    package main
    
    import (
    	"fmt"
    	"log"
    )
    
    func defer1()  {
    	panic("an error occured: stopping")
    	fmt.Println("defer1")
    }
    
    func defer2()  {
    	defer func() {
    		if err := recover();err != nil{
    			log.Printf("panic: v%",err)
    		}
    	}()
    	defer1()
    	fmt.Println("defer2")
    }
    
    func main() {
    	fmt.Println("start....")
    	defer2()
    	fmt.Println("end")
    
    }
    
    

    输出:

    start....
    end
    2019/04/02 00:08:01 panic: v%!(NOVERB)%!(EXTRA string=an error occured: stopping)
    
  • 相关阅读:
    AM335x kernel 4.4.12 i2c eeprom AT24c02驱动移植
    AM335x tscadc platform driver 相关代码跟踪
    Linux kernel make 常用选项介绍
    Linux kernel 文件夹说明
    shell 脚本之获取命令输出字符串以及函数参数传递
    Treeview控件如何获得子节点的所有父节点的名称
    浅谈Delphi高效使用TreeView
    Delphi下Treeview控件基于节点编号的访问
    delphi中TTreeView的使用方法
    学习 TTreeView [2]
  • 原文地址:https://www.cnblogs.com/rickiyang/p/11074165.html
Copyright © 2011-2022 走看看