异常
1.错误和异常
错误:是指可能出现问题的地方出现了问题,这种情况在意料之中
异常:是指不应该出现问题的地方出现了问题,比如引用了空指针,在意料之外。
2.举个例子
用Go来打开一个不存在的文件。
import (
"fmt"
"os"
)
func main() {
f,err:=os.Open("a.txt")
if err != nil{
fmt.Println(err)
return
}
fmt.Println(f.Name(),"打开成功")
}
运行结果是:
open a.txt: The system cannot find the file specified.
Process finished with exit code 0
如果一个函数或者方法返回一个错误,它必须是函数返回的最后一个值,在上述代码中Open函数返回了最后一个值。
处理错误的管用方法是:判断函数或方法的返回的值是否为nil,如果返回的值为nil表示无错误,如果返回的值不是nil,则出现错误,这时,只需要打印错误并从主函数中返回即可
创建error对象
第一种方法:使用New()方法来进行创建
//创建error
err1:=errors.New("自定义错误")
fmt.Println(err1)
fmt.Printf("%T\n",err1)
运行结果为:
自定义错误
*errors.errorString
第二种方法:使用fmt包下的 Errorf函数
//创建error
err2:=fmt.Errorf("错误的信息码:%d",100)
fmt.Println(err2)
fmt.Printf("%T\n",err2)
使用函数处理错误:
首先创建函数,函数类型设定为error
func main() {
err3:=checkNum(-1)
if err3!=nil{
fmt.Println(err3)
}
}
//创建函数,定义错误方式,如果num<0,进行报错
func checkNum(num int) error{
if num<0{
return errors.New("负数为无效数字")
/*
或者可以在这里使用第二种方法创建和返回error对象
err:=fmt.Errorf("负数为无效数字")
return err
*/
}
fmt.Println("正数为有效数字:",num)
return nil
}
如果需要获取更多的错误信息,可以在函数中进行添加
例如:
func main() {
checkOpen("a.txt")
}
func checkOpen(str string) {
f,err4:=os.Open(str)
if err4!=nil{
fmt.Println(err4)
if ins,ok:=err4.(*os.PathError);ok{ //添加更多信息
fmt.Println("1.Op:",ins.Op)
fmt.Println("2.Path",ins.Path)
fmt.Println("3.Err",ins.Err)
}
return
}
fmt.Println(f.Name(),"您已成功打开文件")
}
自定义错误
使用结构体可以储存更多的报错信息,使用起来会比函数更加的方便
第一步就是创建一个表示错误的结构体。在结构体中设置需要使用的报错信息。
第二步就是设置相关函数,自定义错误
第三步就是在主函数中进行引用
例如:
func main(){
//自定义错误
radius :=3.0
area,err5 := circleArea(radius)
if err5!=nil{
fmt.Println(err5)
if err5,ok := err5.(*areaError);ok{
fmt.Printf("半径是:%.2f\n",err5.radius)
}
return
}
fmt.Println("圆形的面积是:",area)
}
type areaError struct { //定义结构体表示错误类型
msg string
radius float64
}
func (e *areaError) Error() string{ //实现error
return fmt.Sprintf("error:半径,%.2f,%s", e.radius, e.msg)
}
func circleArea(radius float64)(float64,error){ //自定义报错方式
if radius<0{
return 0,&areaError{"半径是非法的",radius}
}
return math.Pi * radius * radius,nil
}
也可以这样
func main(){
length,width := 1.0,-1.0
area , err := rectArea(length,width)
if err != nil{
fmt.Println(err)
return
}
fmt.Println("矩形的面积是:",area)
}
type areaError2 struct {
msg string //描述错误
lenght float64 //发生错误后矩形的长度
width float64 //发生错误后矩形的宽度
}
func (e *areaError2) Error() string{
return e.msg
}
func (e *areaError2) lengnthNegative() bool {
return e.lenght < 0
}
func (e *areaError2) widthNegative() bool{
return e.width < 0
}
func rectArea(length,width float64)(float64,error) {
msg := ""
if length<0{
msg = "长度小于0"
}
if width<0{
if msg == ""{
msg = "宽度小于0"
}else{
msg += ",宽度也小于0"
}
}
if msg != ""{
return 0,&areaError2{msg,length,width}
}
return length * width , nil
}