• go语言异常处理


    go语言异常处理

    error接口

    go语言引入了一个关于错误错里的标准模式,即error接口,该接口的定义如下:

    type error interface{
    	Error() string
    }
    

    对于要返回错误的大多数函数来说,大致上都可以定义为如下的模式,将error作为多个返回值中的最后一个,但是这并非是强制要求

    func Foo(param int) (n int,err error){
    	//
    }
    

    调用该函数的时候建议按照如下的方式处理错误情况

    n,err := Foo(0)
    if err != nil{
    	//处理错误
    }else{
    	//处理结果
    }
    
    那么,如何自定义error类型呢,我们以Go库中的实际代码为例来说明,首先,定义一个承载错误信息的类型,因为Go中的接口非常的灵活,你根本不需要像别的语言一样使用继承或则implements来明确指定类型和接口之间的关系,代码如下:
    
    

    type PathError struct{
    Op string
    Path string
    Err error
    }

    这样定义后,编译器如何知道PathError可以当成一个error来传递呢?关键在于下面的代码实现了Error() 方法:

    func (e *PathError) Error() string{
    	return e.Op + " " + e.Path +" " + e.Err.Error()
    }
    
    定义了上述方法之后,就可以直接返回PathError变量了,如下:
    
    

    func test(name string) (fi FIleInfo,err error){
    var stat syscall.Stat_t
    err = syscall.Stat(name,&stat)
    if err != nil{
    return nil,$PathError{"stat",name,err}
    }
    return file,nil
    }

    如果在处理错误的时候要获取错误的详细信息,就需要用到类型的转换知识了:

    fi,err := os.Stat("a.txt")
    if err != nil{
    	if e,ok := err.(*os.PathError);ok && e.Err != nil{
    		//获取PathError类型变量e总的其他信息
    	}
    }
    

    defer

    关键字defer是Go引入的一个很有意思的特性,他能保证在函数中发生异常的情况下,defer定义的语句仍然会被执行,如下:

    func CopyFile(dst,src string) (w int64,err error){
    	srcFile,err := os.Open(src)
    	if err != nil{
    		return	
    	}
    	defer srcFile.Close()
    	dstFile,err := os.Create(dst)
    	if err != nil{
    		return
    	}
    	defer dstFile.Close()
    	return io.Copy(dstFile,srcFile)
    }
    

    即使Copy函数抛出异常,Go仍然会保证文件被正常的关闭,如果据的一句话干不完清理工作的话,可以在defer后加一个匿名函数:

    defer func(){
    	//
    }()
    

    值得注意的是一个函数中可以定义多个defer,并且defer语句的顺序是按照先进后出的顺序执行的,也就是说最后一个defer语句将最先被执行

    panic()和recover()

    GO引入了两个内置的函数panic()和recover()以报告和处理运行时错误和程序中的错误场景

    func panic(interface{})
    func recover() interface{}
    

    当在一个函数中调用panic函数后,正确的执行流程会被立即终止,但函数中之前使用defer关键字延迟执行的语句将正常展开执行,之后该函数将返回到调用函数,并导致逐步向上执行panic流程,直到所属的goroutine中所有正在执行的函数被终止,错误信息将被报告,这个过程成为错误处理流程

    从panic中传入的interface{}中我们可以看出,该函数接收任意类型的数据

    recover用于终止错误处理流程,一般情况下,recover应该在一个使用defer关键字的函数中执行以有效截取错误处理流程,如果在发生异常的goroutine中没有调用recover,会导致该goroutine所属的进程直接退出

    下面是一个常用的场景

    defer func(){
    	if r := recover();r!=nil{
    		log.Printf("Runtime error caught: %v",r)
    	}
    }
    
  • 相关阅读:
    Mongodb常用操作(转载)
    java中对象转换工具类,很好用
    IDEA中配置tomcat出现乱码的解决
    小山博客--面试题答案
    Redis简单配置和使用
    线程的控制和线程池
    进程与线程详细解释
    Quartz .Net(定时框架):
    C#面向对象几组关键字的详解(this,base,dynamic,var,const,readonly,is,as)
    C#设计模式--抽象工厂模式(创建型模式)
  • 原文地址:https://www.cnblogs.com/senlinyang/p/10252849.html
Copyright © 2020-2023  润新知