要解决的问题
- 如何识别具体的错误值
解决方案
- 类型不同&类型范围确定,可以通过判断错误值所属类型,尝试确定错误值范围
- 类型相同&值范围确定,可以通过错误值判等,尝试确定具体的错误值
- 类型不同&类型范围不确定,通过错误的字符串信息通过字符串判等、正则匹配等,尝试对错误值进行判断
解决方案案例 -- Go语言错误值判定
Go语言支持多返回值,对于错误处理有一套近乎通用的解决方案方式,即:
- 函数声明时,在结果列表的最后声明一个error类型的结果,以封装函数执行过程中的错误
- 函数调用时,先判断结果列表中最后一个结果的值是否为nil,以判断函数执行过程是否正常
然而,error类型本质上仅是Go语言自建的一个接口类型,其声明中也仅定义了一个无任何参数声明、结果声明有且仅有一个string类型的Error方法。如果想要进一步对错误进行有效处理,就必须实现错误值的准确识别!
类型不同&类型范围确定
- 类型断言表达式
err := writeFile(file, "new content")
if err != nil{
if errRealVal, ok := err.(*FileReadError); ok{
fmt.Println(fmt.Sprintf("FileReadError: %+v", errRealVal))
}else if errRealVal, ok := err.(*FileWriteError); ok{
fmt.Println(fmt.Sprintf("FileWriteError: %+v", errRealVal))
}else{
fmt.Println(fmt.Sprintf("FileError: %+v", errRealVal))
}
}
- switch语句
_, err := readFile(file)
if err != nil{
switch errRealType := err.(type) {
case *FileReadError:
fmt.Println(fmt.Sprintf("FileReadError: %+v", errRealType))
case *FileWriteError:
fmt.Println(fmt.Sprintf("FileWriteError: %+v", errRealType))
default:
fmt.Println(fmt.Sprintf("FileError: %+v", errRealType))
}
}
源代码路径:../../identify-specific-error/same_type&known_type_range/demo.go
类型相同&值范围确定
- 判等表达式
err := validateFile(file)
if err != nil{
if err == &FileReadError{
fmt.Println(fmt.Sprintf("FileError: %+v", FileReadError))
}else if err == &FileWriteError {
fmt.Println(fmt.Sprintf("FileError: %+v", FileWriteError))
}else{
fmt.Println(fmt.Sprintf("FileError"))
}
}
- switch语句
err := validateFile(file)
if err != nil{
switch err {
case &FileReadError:
fmt.Println(fmt.Sprintf("FileError: %+v", FileReadError))
case &FileWriteError:
fmt.Println(fmt.Sprintf("FileError: %+v", FileWriteError))
default:
fmt.Println(fmt.Sprintf("FileError"))
}
}
源代码路径:../../identify-specific-error/same_type&known_value_range/demo.go
类型不同&类型范围不确定
- 字符串匹配
err := validateFile(file)
if err != nil{
errMsg := err.Error()
if strings.Contains(errMsg,"read"){
fmt.Printf("file read failure: %s\n", errMsg)
}else if strings.Contains(errMsg,"write"){
fmt.Printf("file write failure: %s\n", errMsg)
}else {
fmt.Printf("file has failure: %s\n", errMsg)
}
}
源代码路径:../../identify-specific-error/diff_type&unknown_type_range/demo.go