首页 > 编程笔记 > Go语言笔记 阅读:10

Go语言自定义error的3种方式(附带实例)

程序在运行时出现错误,系统给出相应的错误信息,但是这种错误信息看起来不够直观。Go 语言允许用户自定义错误描述信息。

本节介绍自定义 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
参数说明如下:
使用 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

在上述代码中,定义了用于计算长方形面积的函数 area(),两个参数分别表示长方形的长和宽。在函数中判断传入的长和宽是否小于或等于 0,如果小于或等于 0,则使用 fmt 包的 Errorf() 函数自定义错误信息,否则计算长方形的面积。在主函数中两次调用 area() 函数,第一次调用函数传递的是一个负数,所以输出自定义的错误信息。第二次调用函数传递的两个值都是正数,所以输出长方形的面积。

相关文章