Golang学习之error篇
以一个打开系统文件为例,在error文件夹下有个hello.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | package main
  import ( 	"fmt" 	"os" )
  func main() { 	file, err := os.Open("C:\\Users\\42012\\Desktop\\代码\\error\\hello.txt") 	if err != nil { 		fmt.Println("open file error") 	} 	fmt.Println(file, err) 	fmt.Printf("Error的类型是:%T", err) }
 
   | 
 
正常运行的结果是
1 2
   | &{0xc000072780} <nil> Error的类型是:<nil>
  | 
 
当我们把hello.txt改成hello1.txt后,结果是
1 2 3
   | open file error <nil> open C:\Users\42012\Desktop\代码\error\hello1.txt: The system cannot find the file specified. Error的类型是:*os.PathError
   | 
 
控制台打印出了PathError路径错误,我们就可以根据error的类型和提示,快速定位代码中有问题的代码片段,并且加以修正。
自定义error
虽然golang有很多自带的error类型和提示,但是并不能完全覆盖所有的错误。
例如定义一个除法函数,当我们输入的被除数出现0时,整个程序就崩溃无法执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | package main
  import ( 	"fmt" )
  func DivisionForInt(dividend, divsor int) int { 	return dividend / divsor }
  func main() { 	fmt.Println(DivisionForInt(10, 5)) 	fmt.Println(DivisionForInt(10, 0)) 	fmt.Println(DivisionForInt(0, 100))
  }
 
   | 
 
这时候运行程序得到的结果是
1 2 3 4 5
   | 2 panic: runtime error: integer divide by zero
  goroutine 1 [running]: main.DivisionForInt(...)
   | 
 
可以看出在执行完第一个除法后,第二个除法的被除数为0,导致程序直接出现了panic崩溃,第三个除法也不会继续执行了。那么为了让程序更加健壮,我们需要对这个错误类型进行兼容处理,可以通过自定义error来解决。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | package main
  import ( 	"errors" 	"fmt" )
  var errDivisionByZero = errors.New("被除数不能为0")
  func DivisionForInt(dividend, divsor int) (int, error) { 	if divsor == 0 { 		return 0, errDivisionByZero 	} 	return dividend / divsor, nil }
  func main() { 	fmt.Println(DivisionForInt(10, 5)) 	fmt.Println(DivisionForInt(10, 0)) 	fmt.Println(DivisionForInt(0, 100))
  }
 
   | 
 
通过new得到一个自定义的error,在程序中对除数先进行判断,如果是0的话返回这个error给主程序
1 2 3
   | 2 <nil> 0 被除数不能为0 0 <nil>
   | 
 
程序就不会发生崩溃,后面的除法也可以正常的运行。
另一种实现方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
   | package main
  import ( 	"fmt" )
  type errDiv struct { 	errStr string }
  func (e *errDiv) Error() string { 	return e.errStr }
  func DivisionForInt2(dividend, divsor int) (int, error) { 	if divsor == 0 { 		return 0, &errDiv{ 			errStr: "除数不能为0哦", 		} 	} 	return dividend / divsor, nil }
  func main() { 	fmt.Println(DivisionForInt2(10, 5)) 	fmt.Println(DivisionForInt2(10, 0)) 	fmt.Println(DivisionForInt2(0, 100)) }
 
   | 
 
panic和recover