围棋产生错误的方式有这么多,你真的了解它们各自的应用场景吗?
所以接口只有一个返回字符串的错误函数,所有类型只要实现了这个函数都会创建一个错误类型。
产生错误的方式包括错误。新的,fmt。Errorf,以及用户定义的错误接口的类型。
2.1是由错误创建的。新方法。
这种方法产生的错误通常是可预测的错误。简单来说,调用者可以通过这个错误消息清楚地知道哪里出错了,不需要添加其他上下文信息,我们将在下面的例子中详细解释。
查看新方法的实现,我们可以看到它实际上返回了一个ErrorString结构,该结构包含一个String属性并实现了error方法。代码如下:
错误。新使用场景1:
通过错误创建局部变量或匿名变量。新函数,并且不判断调用函数中的值或类型,而只打印或记录错误日志的场景。
使用示例1:
以下代码摘自源代码/src/net//src/net//http/transport . go当请求体中的url地址为nil时,返回的错误为“http: nil Request。URL”,这意味着请求中的URL字段为零。以及当头为nil时返回的错误:“http: nilrequest。Header”,表示请求正文中的头字段为零。
错误。新的使用场景2:
分配由错误创建的错误。一个新的全局变量,我们称之为哨兵错误。sentinel错误变量可用于在处理时比较这些值。
使用示例:源代码/src/io/io.go中定义的哨兵错误变量EOF代表文件的结尾。
在beego项目中,beego/core/utils/file.go文件中有这样一个应用。读取文件时,如果遇到的错误不是文件末尾的错误,会直接返回。如果是文件末尾的错误,for循环会被中断,说明文件已经读取了文件中的所有内容。如下所示:
2.2由fmt创建。Errorf方法。
使用场景1:不带%w占位符:
创建错误时,不能通过错误创建的字符串信息来描述错误。新增,但是需要通过占位符添加更多的上下文信息,也就是动态信息。
使用示例:不带%w占位符:
下面的例子摘自gorm/schema/relationship.go的部分代码,当foreignKey不合法时,通过fmt.errorf返回一个带有特定外键的错误(“无效外键:% s”,foreign key)。因为外键值只能在运行时确定。代码如下:
使用场景2:带有%w的占位符:
在某些场景下,调用者需要知道原始错误信息,一般通过错误判断错误链是否包含特定类型的原始错误值。就是功能。
用%w占位符创建的错误消息实际上形成了一个错误链。其用法如下:
让我们再来看看源代码:
根据源代码,如果%w占位符包含在fmt中。Errorf,创建wrapError结构类型的值。让我们来看看wrapError结构的定义:
err字段是原始错误,msg是格式化的错误消息。
使用示例:带有%w的占位符:
假设我们有一个从数据库中查询合同的函数。当来自数据库的查询显示记录为空时,sql。将返回ErrNoRows错误。我们用一个%w占位符将错误包装起来,并返回给调用者。
好了,现在GetContract的调用者可以知道原来的错误消息了。在调用者逻辑中,我们可以使用错误。是确定sql的值。ErrNoRows包含在err中。让我们看看调用者的代码:
使用场景:这是相对于错误的。新增,适用于可预测错误的定义。当发生不可预测的错误时,您需要自定义错误类型。
使用示例:我们以go source code /src/io/fs/fs.go文件中的源代码为例,看看自定义错误类型需要包含哪些元素。
首先看结构。有一个Err接口类型的Err,它表示错误源。因为根据上面的解释,当错误层被传回调用者时,我们需要跟踪每一层的原始错误信息,所以我们需要这个字段来包装错误,形成一个错误链。此外,还有两个字段Op和Path,分别表示导致错误的操作和操作的路径。这两个字段就是所谓的意外错误:不确定哪个路径发生了什么错误。
让我们看看这种错误类型在代码中的应用:
应用1:go的文件src/embed/embed.go中的代码,在读取一个目录时,返回一个PathError类型,意思是读取目录时,由于是目录,文件内容不能直接读取。
应用二:在go的文件src/embed/embed.go中的代码中,有一个文件读取函数。当偏移量小于0时,返回PathError,这意味着在读取文件时参数不正确。
fs的定义。ErrInvalid如下:
可以看出,PathError中三个字段的值是不可预测的,需要在程序运行时详细确定,所以在这种场景下,需要自定义错误类型。
此外,我们还注意到,在这个自定义类型中有一个Unwrap函数,主要与errors结合使用。是和错误。As,因为这两个函数是用来逐个解包错误链的。
根据上一节,我们可以通过%w个占位符将错误组织成一个错误链。
错误的功能。Is是判断错误链中是否有等于指定错误值的错误,等于= =运算符。注意,这是一个特定的错误值,就像gorm中定义的ErrRecordNotFound:
然后我们可以使用错误。是这样的:
错误。作为函数,该函数用于检查错误链中的错误是否为特定类型。下面的代码示例摘自etcd项目中etcd/server/embed/config _ logging . go中的部分代码,代表err链中是否有可视为json的错误。语法错误类型。如果是,将err中的错误值赋给SyntaxiError变量。代码如下:
本文从应用场景的角度阐述了各种造错方式的实际应用场景。示例中的代码尽量选自golang源代码或开源项目。同时,每个应用场景都不是绝对的,需要灵活应用。希望这篇文章能在实际使用中对大家有所帮助。