Go语言自定义error的3种方式(附带实例)
程序在运行时出现错误,系统给出相应的错误信息,但是这种错误信息看起来不够直观。Go 语言允许用户自定义错误描述信息。
本节介绍自定义 error 错误信息的 3 种方法。
例如,定义一个计算数字平方根的函数,如果数字小于0,就返回自定义的错误信息。代码如下:
修改上述示例代码,使用 error 接口自定义的 Error() 函数获取错误信息。代码如下:
【实例】输出除数为 0 时的错误信息。定义用于计算两个数的除法的函数,当除数为 0 时显示自定义的错误信息,当除数不为 0 时输出计算结果。代码如下:
使用 fmt 包的 Errorf() 函数自定义错误信息,打印该错误信息和错误发生的时间。代码如下:
【实例】输出计算长方形面积时的错误信息。定义用于计算长方形面积的函数,当长方形的长或高小于或等于 0 时显示自定义的错误信息,否则输出计算结果。代码如下:
本节介绍自定义 error 错误信息的 3 种方法。
使用errors包中的New()函数
自定义错误信息最简单的方法就是调用 errors 包中的 New() 函数。例如,定义一个计算数字平方根的函数,如果数字小于0,就返回自定义的错误信息。代码如下:
package main import ( "errors" "fmt" "math" ) func Sqrt(num float64) (float64, error) { if num < 0 { // 自定义错误信息 return -1, errors.New("错误:负数没有平方根!") } return math.Sqrt(num), nil } func main() { result, err := Sqrt(-2) //调用函数 if err != nil { fmt.Print(err) //输出错误信息 } else { fmt.Print(result) //输出计算结果 } }运行结果为:
错误:负数没有平方根!
在上述代码中,使用 errors 包中的 New() 函数返回错误信息。因为在调用 Sqrt() 函数时传入负数 −2,所以输出自定义的错误信息“错误:负数没有平方根!”。使用error接口自定义Error()函数
除了使用 errors 包的 New() 函数,还可以使用 error 接口自定义 Error() 函数,返回自定义的错误信息。修改上述示例代码,使用 error 接口自定义的 Error() 函数获取错误信息。代码如下:
package main import ( "fmt" "math" ) //定义结构体 type sqrtError struct { num float64 } //定义结构体 Error()函数 func (s sqrtError) Error() string { //自定义错误信息 return fmt.Sprintf("错误:%v 没有平方根", s.num) } func Sqrt(num float64) (float64, error) { if num < 0 { return -1, sqrtError{num: num} } return math.Sqrt(num), nil } func main() { result, err := Sqrt(-2) //调用函数 if err != nil { fmt.Print(err) //输出错误信息 } else { fmt.Print(result) //输出计算结果 } }运行结果为:
错误:-2没有平方根
在上述代码中,定义了结构体 sqrtError 和结构体的 Error() 函数。当调用 Sqrt() 函数时,因为传入的参数小于 0,所以返回错误信息,将错误信息保存在变量 err 中,而 err 的值是 Sqrt() 函数中返回的结构体实例。当打印 err 的值时,自动调用 err 的 Error() 函数,即结构体的 Error() 函数,因此输出自定义的错误信息。【实例】输出除数为 0 时的错误信息。定义用于计算两个数的除法的函数,当除数为 0 时显示自定义的错误信息,当除数不为 0 时输出计算结果。代码如下:
package main import ( "fmt" ) //定义结构体 type divide struct { dividend float64 divisor float64 } //定义结构体 Error()函数 func (d divide) Error() string { //自定义错误信息 err := ` 被除数:%v 除数:0 错误:除数不能为0 ` return fmt.Sprintf(err, d.dividend) } func divideBy(dividend float64, divisor float64) (float64, error) { if divisor == 0 { return -1, divide{ dividend: dividend, divisor: divisor, } } return dividend / divisor, nil } func main() { result, err := divideBy(6, 0) //调用函数 if err != nil { fmt.Print(err) //输出错误信息 } else { fmt.Print(result) //输出计算结果 } }运行结果为:
被除数:6
除数:0
错误:除数不能为0
使用fmt包的Errorf()函数
通过 fmt 包的 Errorf() 函数可以格式化创建描述性的错误信息。该函数的语法格式如下:func Errorf(format string, a ...interface{}) error参数说明如下:
- format:带有占位符的错误信息。例如,%s 表示字符串,%d 表示整数;
- a ...interface{}:可选,使用的常量、变量名称或内置函数。
使用 fmt 包的 Errorf() 函数自定义错误信息,打印该错误信息和错误发生的时间。代码如下:
package main import ( "fmt" "time" ) func main() { //定义常量 const name, id = "Tom", 10 //自定义错误信息 err := fmt.Errorf("用户 %q (id %d) 不存在", name, id) fmt.Println(err) fmt.Printf("错误发生时间:%v", time.Now()) }运行结果为:
用户 "Tom" (id 10) 不存在
错误发生时间:2022-10-18 14:36:44.6387491 +0800 CST m=+0.007259101
【实例】输出计算长方形面积时的错误信息。定义用于计算长方形面积的函数,当长方形的长或高小于或等于 0 时显示自定义的错误信息,否则输出计算结果。代码如下:
package main import ( "fmt" ) //自定义函数,计算长方形的面积 func area(length float64, width float64) (float64, error) { if length <= 0 { return -1, fmt.Errorf("长方形的长是%v,长不能小于或等于0", length) } if width <= 0 { return -1, fmt.Errorf("长方形的宽是%v,宽不能小于或等于0", width) } return length * width, nil } func main() { result, err := area(6, -3) //调用函数 if err != nil { fmt.Println(err) //输出错误信息 } else { fmt.Printf("长方形的面积为:%v\n", result) //输出计算结果 } result, err = area(6, 3) //调用函数 if err != nil { fmt.Println(err) //输出错误信息 } else { fmt.Printf("长方形的面积为:%v\n", result) //输出计算结果 } }运行结果为:
长方形的宽是-3,宽不能小于或等于0
长方形的面积为:18