如何处理计算机启动文件路径错误? (如何处理计算机启动文件路径错误?啊) 前言

例如,在介绍函数章节中,Go没有语言try...catch这种异常处理机制不能像java执行抛异常操作, 但是在Go可用于语言defer...recover...panic的机制来实现类似try...catch效果;今天我们将讨论这个话题;

Go为什么不设计?try...catch异常机制


java里使用try/catch 机制,声明函数定义Expception使用层次不够简单,调用时异常处理过度泛滥,利用内存栈空间从底层向更高层次抛掷异常资源过度消耗。Go未使用设计机制java里try...catch但也实现了类似的异常机制 “捕捉” 将异常放入机制中,但更轻,只作为最终手段(处理错误)。


GO预定义了一个error接口类型;用错误值表示错误状态, 与其他数据类型一样,错误类型也是一种数据类型,可作为参数或返回值


type error interface{ Error() string }




错误定义


在GO语言里,没有类似Java如此强烈的面向对象特征, 可通过结构实现Error定义错误对象类型的方法,例如


type NullException struct{}?func (ne *NullException) Error() string{ return "NullPointException"}?func Trim(s *string) (string, error){ if s == nil{ return "", &NullException{}}else{ return strings.TrimSpace(*s), nil }}

例如,上述代码定义了异常对象的类型NullException; 可以通过 err:=&NullException{}生成错误对象;

上面是通过type struct定义错误; 除此之外,还可以使用errors内置函数包errors.New来产生一个新的错误类型对象;如下面代码:


func Trim(s *string) (string, error){ if s == nil{ return "", errors.New("NullPointException") }else{ return strings.TrimSpace(*s), nil }}



与上述方法相比,代码更简单,很多源代码都是这样写的; 让我们来看看一个完整的例子


func TestException(t *testing.T){ var s *string? if rtn, err := Trim(s); err == nil{ fmt.Printf("Trim(%v)=%v \ ", s, rtn) }else{ fmt.Printf("Trim(%v) throw exception: %v \ ", s, err) }? var a string if rtn, err := Trim(&a); err == nil{ fmt.Printf("Trim(%v)=%v \ ", &a, rtn) }else{ fmt.Printf("Trim(%v) throw exception: %v \ ", &a, err) }}??===== OUTPUT ======== RUN TestExceptionTrim(<nil>) throw exception: NullPointException Trim(0xc000273a10)= --- PASS: TestException (0.00s)PASS


在上述代码中,第一次调用Trim(s),s定义为string对于指针类型的变量,定义后自动初始化为指针类型nil,所以Trim(s)调用会返回NullExpcetion对象; 也就打印出Trim(<nil>) throw exception: NullPointException ;



对于第二个Trim(&a);a定义为string类型对象,string定义基本类型对象后,自动初始化为空字符串("";),所以Trim(&a)调用,传入string指针不为空nil(而是空字符串"";变量指针),此时返回的错误对象是nil,没有错;返回是空字串Trim以后的结果,还是空字符串;也就打印出Trim(0xc000273a10)=



错误的判断


有时在函数处理过程中,可能会出现不同类型的错误条件;例如,对于文件处理场景;有时可能是文件路径错误,有时可能是文件的状态错误;当发生各种错误时,对错误的判断具有使用场景的价值。使用类型断言或类型判断(type-switch)这是一种非常有效的方法来处理这个场景,并且可以 根据错误场景进行补救和恢复。使用类型断言或类型判断(type-switch)这是一种非常有效的方法来处理这个场景,并且可以 根据错误场景进行补救和恢复。


看下面的代码


type NotFoundException struct{}?func (ne NotFoundException) Error() string{ return "NotFoundException"}?type NotAllowException struct{}?func (ne NotAllowException) Error() string{ return "NotAllowException"}?func ReadFile(path string) ([]byte, error){ n := len(path) if n <= 1{ return nil, NotFoundException{}}else if n <= 12{ return nil, NotAllowException{}}? return[]byte(path), nil}?func ReadOne(path string){ if rtn, err := ReadFile(path); err == nil{ fmt.Printf("ReadFile(%v)=%v \ ", path, rtn) }else{ switch err.(type){ case NotFoundException: fmt.Printf("ReadFile(%v) throw NotFoundException: %v \ ", path, err) case NotAllowException: fmt.Printf("ReadFile(%v) throw NotAllowException: %v \ ", path, err) default: fmt.Printf("ReadFile(%v) throw UnknowException: %v \ ", path, err) }}}



上面的代码ReadOne在函数中,有错误判断的处理方法; 在ReadOne函数里调用ReadFile函数,在ReadFile如果函数简单地实现,path长度不大于1,返回错误NotFoundException;如果path长度不大于12;返回错误;NotAllowException;其他正常返回;


ReadFile函数错误类型可以返回多种类型;ReadOne函数是通过的type-swtich的方式,对err判断对象的类型; 如果是NotFoundException执行逻辑;如果是,NotAllowException如果两种错误类型不匹配,则执行第三段逻辑; 错误类型NotFoundException和NotAllowException都在ReadOne定义函数上方的实际调用代码:


func TestException2(t *testing.T){ var s string? s = "/" ReadOne(s)? s = "/" ReadOne(s)? s = "/readme.txt" ReadOne(s)? s = "/home/readme.txt" ReadOne(s)}?===== OUTPUT ======== RUN TestException2ReadFile(/) throw NotFoundException: NotFoundException ReadFile(/readme.txt) throw NotAllowException: NotAllowException ReadFile(/home/readme.txt)=[47 104 111 109 101 47 114 101 97 100 109 101 46 116 120 116]--- PASS: TestException2 (0.00s)PASS






结束语


错误处理是每种编程语言中需要面对的问题,也是编程过程中必须考虑的问题;如果处理错误,代码的稳定性会很好。今天的文章通过代码实例向您介绍GO语言中有一些关于错误处理的知识;我们用代码练习,写一个更稳定的程序。今天的文章通过代码实例向您介绍GO语言中有一些关于错误处理的知识;我们用代码练习,写一个更稳定的程序。



欢迎继续关注 GO语言编程训练

?