go教程10
1. 自定义错误
在上一教程里,我们学习了 Go 中的错误是如何表示的,并学习了如何处理标准库里的错误。我们还学习了从标准库的错误中提取更多的信息。
在本教程中,我们会学习如何创建我们自己的自定义错误,并在我们创建的函数和包中使用它。我们会使用与标准库中相同的技术,来提供自定义错误的更多细节信息。
使用 New 函数创建自定义错误
创建自定义错误最简单的方法是使用 errors
包中的 New
函数。
在使用 New 函数 创建自定义错误之前,我们先来看看 New
是如何实现的。如下所示,是 errors
包 中的 New
函数的实现。
// Package errors implements functions to manipulate errors.
package errors
// New returns an error that formats as the given text.
text
errorString
text
}
// errorString is a trivial implementation of error.
errorString
s
}
e
errorString
e
s
}
New
函数的实现很简单。errorString
是一个结构体类型,只有一个字符串字段 s
。第 14 行使用了 errorString
指针接受者(Pointer Receiver),来实现 error
接口的 Error() string
方法。
第 5 行的 New
函数有一个字符串参数,通过这个参数创建了 errorString
类型的变量,并返回了它的地址。于是它就创建并返回了一个新的错误。
现在我们已经知道了 New
函数是如何工作的,我们开始在程序里使用 New
来创建自定义错误吧。
我们将创建一个计算圆半径的简单程序,如果半径为负,它会返回一个错误。
package main
)
radius
radius
errors
math
Pi
radius
radius
}
radius
area
err
radius
err
fmt
err
fmt
area
}
在上面的程序中,我们检查半径是否小于零(第 10 行)。如果半径小于零,我们会返回等于 0 的面积,以及相应的错误信息。如果半径大于零,则会计算出面积,并返回值为 nil
的错误(第 13 行)。
在 main
函数里,我们在第 19 行检查错误是否等于 nil
。如果不是 nil
,我们会打印出错误并返回,否则我们会打印出圆的面积。
在我们的程序中,半径小于零,因此打印出:
Area calculation failed, radius is less than zero
使用 Errorf 给错误添加更多信息
上面的程序效果不错,但是如果我们能够打印出当前圆的半径,那就更好了。这就要用到 fmt
包中的 Errorf
函数了。Errorf
函数会根据格式说明符,规定错误的格式,并返回一个符合该错误的字符串。
接下来我们使用 Errorf
函数来改进我们的程序。
package main
)
radius
radius
fmt
radius
math
Pi
radius
radius
}
radius
area
err
radius
err
fmt
err
fmt
area
}
在上面的程序中,我们使用 Errorf
(第 10 行)打印了发生错误的半径。程序运行后会输出:
Area calculation failed, radius -20.00 is less than zero
使用结构体类型和字段提供错误的更多信息
错误还可以用实现了 error
接口的结构体来表示。这种方式可以更加灵活地处理错误。在上面例子中,如果我们希望访问引发错误的半径,现在唯一的方法就是解析错误的描述信息 Area calculation failed, radius -20.00 is less than zero
。这样做不太好,因为一旦描述信息发生变化,程序就会出错。
我们会使用标准库里采用的方法,在上一教程中“断言底层结构体类型,使用结构体字段获取更多信息”这一节,我们讲解了这一方法,可以使用结构体字段来访问引发错误的半径。我们会创建一个实现 error
接口的结构体类型,并使用它的字段来提供关于错误的更多信息。
第一步就是创建一个表示错误的结构体类型。错误类型的命名约定是名称以 Error
结尾。因此我们不妨把结构体类型命名为 areaError
。
areaError
err
radius
}
上面的结构体类型有一个 radius
字段,它存储了与错误有关的半径,而 err
字段存储了实际的错误信息。
下一步是实现 error
接口。
e
areaError
fmt
e
radius
e
err
}
在上面的代码中,我们使用指针接收者 *areaError
,实现了 error
接口的 Error() string
方法。该方法打印出半径和关于错误的描述。
现在我们来编写 main
函数和 circleArea
函数来完成整个程序。
package main
)
areaError
err
radius
}
e
areaError
fmt
e
radius
e
err
}
radius
radius
areaError
radius
math
Pi
radius
radius
}
radius
area
err
radius
err
err
ok
err
areaError
ok
fmt
err
radius
fmt
err
fmt
area
}
在上面的程序中,circleArea
(第 17 行)用于计算圆的面积。该函数首先检查半径是否小于零,如果小于零,它会通过错误半径和对应错误信息,创建一个 areaError
类型的值,然后返回 areaError
值的地址,与此同时 area
等于 0(第 19 行)。于是我们提供了更多的错误信息(即导致错误的半径),我们使用了自定义错误的结构体字段来定义它。
如果半径是非负数,该函数会在第 21 行计算并返回面积,同时错误值为 nil
。
在 main
函数的 26 行,我们试图计算半径为 -20 的圆的面积。由于半径小于零,因此会导致一个错误。
我们在第 27 行检查了错误是否为 nil
,并在下一行断言了 *areaError
类型。如果错误是 *areaError
类型,我们就可以用 err.radius
来获取错误的半径(第 29 行),打印出自定义错误的消息,最后程序返回退出。
如果断言错误,我们就在第 32 行打印该错误,并返回。如果没有发生错误,在第 35 行会打印出面积。
该程序会输出:
Radius -20.00 is less than zero
下面我们来使用上一教程提到的第二种方法,使用自定义错误类型的方法来提供错误的更多信息。
使用结构体类型的方法来提供错误的更多信息
在本节里,我们会编写一个计算矩形面积的程序。如果长或宽小于零,程序就会打印出错误。
第一步就是创建一个表示错误的结构体。
areaError
err
length
width
}
上面的结构体类型除了有一个错误描述字段,还有可能引发错误的宽和高。
现在我们有了错误类型,我们来实现 error
接口,并给该错误类型添加两个方法,使它提供了更多的错误信息。
e
areaError
e
err
}
e
areaError
e
length
}
e
areaError
e
width
}
在上面的代码片段中,我们从 Error() string
方法中返回了关于错误的描述。当 length
小于零时,lengthNegative() bool
方法返回 true
,而当 width
小于零时,widthNegative() bool
方法返回 true
。这两个方法都提供了关于错误的更多信息,在这里,它提示我们计算面积失败的原因(长度为负数或者宽度为负数)。于是我们就有了两个错误类型结构体的方法,来提供更多的错误信息。
下一步就是编写计算面积的函数。
length
width
err
length
err
width
err
err
err
err
areaError
err
length
width
length
width
}
上面的 rectArea
函数检查了长或宽是否小于零,如果小于零,rectArea
会返回一个错误信息,否则 rectArea
会返回矩形的面积和一个值为 nil
的错误。
让我们创建 main
函数来完成整个程序。
length
width
area
err
length
width
err
err
ok
err
areaError
ok
err
fmt
err
length
err
fmt
err
width
fmt
err
fmt
area
}
在 main
程序中,我们检查了错误是否为 nil
(第 4 行)。如果错误值不是 nil
,我们会在下一行断言 *areaError
类型。然后,我们使用 lengthNegative()
和 widthNegative()
方法,检查错误的原因是长度小于零还是宽度小于零。这样我们就使用了错误结构体类型的方法,来提供更多的错误信息。
如果没有错误发生,就会打印矩形的面积。
下面是整个程序的代码供你参考。
package main
areaError
err
length
width
}
e
areaError
e
err
}
e
areaError
e
length
}
e
areaError
e
width
}
length
width
err
length
err
width
err
err
err
err
areaError
err
length
width
length
width
}
length
width
area
err
length
width
err
err
ok
err
areaError
ok
err
fmt
err
length
err
fmt
err
width
fmt
err
fmt
area
}
该程序会打印输出:
error: length -5.00 is less than zero
error: width -9.00 is less than zero
在上一教程错误处理中,我们介绍了三种提供更多错误信息的方法,现在我们已经看了其中两个示例。
第三种方法使用的是直接比较,比较简单。我留给读者作为练习,你们可以试着使用这种方法来给出自定义错误的更多信息。
本教程到此结束。
简单概括一下本教程讨论的内容:
- 使用
New
函数创建自定义错误 - 使用
Error
添加更多错误信息 - 使用结构体类型和字段,提供更多错误信息
- 使用结构体类型和方法,提供更多错误信息
祝你愉快。
本文来自博客园,作者:易先讯,转载请注明原文链接:https://www.cnblogs.com/gongxianjin/p/17981814
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具