1 error
1.1 error的相关介绍
error一般是处理一些比较低级的错误,不会造成程序中断或者宕机。下面是go源码中error的相关内容:
// 接口定义
type error interface{
Error() string
}
package errors
// 错误的结构体定义
type errorString struct{
text string
}
// 该errorString结构体的方法的实现
func (e *errorString)Error() string{
return e.text
}
// 最终可以通过这个函数获取一个errorString结构,从而可以调用Error方法。
func New(text string) error{
return &errorString(text)
}
例如简单使用标准库的两个错误函数:
package main
import (
"errors"
"fmt"
)
func main(){
err1 := fmt.Errorf("%s", "this is a Errorf")
fmt.Println("err1: ", err1)
err2 := errors.New("this New error")
fmt.Println("err2: ", err2)
}
1.2 error常用的用法
package main
import (
"errors"
"fmt"
)
// error 为nil说明正常,否则报错,信息从errors.New获取
func MyDiv(a, b int) (result int, err error){
err = nil
if b == 0 {
err = errors.New("分母不能为0")
}else{
result = a/b
}
return // 等价于 return result, err
}
func main(){
ret, err := MyDiv(2, 2)
if err == nil{
fmt.Println("ret = ", ret)
}else{
fmt.Println("表达式存在非法值, err: ", err)
}
ret, err = MyDiv(2, 0)
if err == nil{
fmt.Println("ret = ", ret)
}else{
fmt.Println("表达式存在非法值, err: ", err)
}
}
2 panic
- 1)panic一般是发生了致命的错误时才会被调用,例如数组越界,空指针等等,当然我们也可以手动调用panic()函数去触发。类似C语言的assert()断言函数。
2.1 显示手动调用panic
package main
import "fmt"
func testa(){
fmt.Println("aaaaaaaaaaaaaa")
}
func testb(){
//fmt.Println("bbbbbbbbbbbbbb")
// 手动调用panic()会触发断言
panic("manual triggered assertions, the program breaks")
}
func testc(){
fmt.Println("ccccccccccccccc")
}
func main(){
testa()
testb()
testc()
}
相关错误如下:
2.2 数组越界造成panic
package main
import "fmt"
func testa(){
fmt.Println("aaaaaaaaaaaaaa")
}
func testb(index int){
//fmt.Println("bbbbbbbbbbbbbb")
// 手动调用panic()会触发断言
// panic("manual triggered assertions, the program breaks")
// 数组越界造成panic断言
var x [10]int
fmt.Println("x: ", x[index])
}
func testc(){
fmt.Println("ccccccccccccccc")
}
func main(){
testa()
testb(10) // 数组越界触发断言
testc()
}
3 recover函数
当发生panic错误时,会中断程序,但是有时候我们又不想程序中断,我们可以使用recover函数去捕获这个中断。
但是注意:
- 1)recover()只有在defer调用的函数有效。当该函数中定义了defer,并且该函数发生了panic错误,那么该错误会被捕获,程序会恢复正常。
例如:
package main
import "fmt"
func testa(){
fmt.Println("aaaaaaaaaaaaaa")
}
func testb(index int){
//fmt.Println("bbbbbbbbbbbbbb")
// 手动调用panic()会触发断言
// panic("manual triggered assertions, the program breaks")
// 设置recover
defer func() {
if err := recover(); err != nil{
//fmt.Println("errInfo: ", recover())// 不要再次调用recover()作为信息,因为此时调用是正常的,
//因为没有错误了,错误已经在if中被捕获掉
fmt.Println("errInfo: ", err)
}
}()
// 数组越界造成panic断言
var x [10]int
fmt.Println("x: ", x[index])
}
func testc(){
fmt.Println("ccccccccccccccc")
}
func main(){
testa()
testb(10) // 数组越界触发断言
testc()
}