端午小长假南铁预计发送旅客502万人次 客流最高峰预计在6月24日 每日聚焦
记者从中国铁路南昌局集团有限公司(以下简称南铁)获悉,2023年端午假
2023-06-15预计将于 2023 年 2 月发布的 Go 1.20 有一个小的变化,对于那些大量使用错误包装的应用程序来说,可能会有效改进它们的错误处理方法。
让我们看一下它的用法,但首先,需要简要回顾一下什么是错误包装。如果你已经掌握了可以直接跳到下面的 “Go 1.20 新功能” 部分以获取新的信息。
Go 中的错误是实现一个非常简单的接口:
(资料图片仅供参考)
typeerrorinterface{Error()string}
错误类型可以是任何东西,从string本身到int,但通常它们是struct类型。下面这个例子来自标准库:
typeerrstruct{sstring}func(e*err)Error()string{returne.s}
要检查 Go 中的错误,你只需比较一个值(在本例中为int值):
iferr==io.EOF{//...}
第二种常见的用法是检查错误的类型,那也意味着要写更多的代码:
ifnerr,ok:=err.(net.Error){//...(usenerrwhichisanet.Error)}
在上面的例子中,类型断言测试类型net.Error的err值,并创建一个新变量nerr,它可以在 if 语句中使用。Go 中的错误方便理解、易于使用且非常高效。
错误包装从 Go 1.13 开始,引入了错误包装。包装允许将错误嵌入到其他错误中,就像在其他语言中包装异常一样。这非常实用,比如函数遇到 “record not found” 错误时,可以向错误信息中添加更多上下文信息,例如 “unknown user: record not found”。
Go 中错误包装设计背后的有趣想法是:契约不用关心错误类型、结构或它们是如何创建的。而唯一关注的是解包过程和转换为字符串,因为这两者是必须的。这就非常容易实现:支持解包的错误类型必须实现Unwrap() error方法。
标准库中没有(命名的)接口可以向您展示,因为接口是隐式实现的,没有必要单独写一个。这里我们写一个只是为了更好说明这篇文章:
typeWrappedErrorinterface{Unwrap()error}
我们来看看 Go 标准库(实际上是 package fmt)中是如何实现包装错误的:
typewrapErrorstruct{msgstringerrerror}func(e*wrapError)Error()string{returne.msg}func(e*wrapError)Unwrap()error{returne.err}
由于上面错误类型实现了Error() string方法,所以说 Go 中的错误实际上最终是字符串并没有错,因此需要一种创建这些字符串的良好机制。这就是标准库中的函数fmt.Errorf发挥作用的地方:
varRecordNotFoundErr=errors.New("notfound")constname,id="lzap",13werr:=fmt.Errorf("unknownuser%q(id%d):%w",name,id,recordNotFoundErr)fmt.Println(werr.Error())
一个特殊格式的动词%w,每次调用只能使用一次(稍后会详细介绍),用于错误参数。除此之外,该函数的工作方式类似于fmt.Printf函数。下面的例子打印了这个结果:
unknownuser"lzap"(id13):notfound
如你所见,错误包装本质上是一个链表。要解包错误,请使用errors.Unwrap函数,该函数将为链表中的最后一个错误值返回nil。要检查错误类型或值,需要遍历整个列表,这对于需要进行频繁的错误检查不太实用。幸运的是,有两个辅助函数可以做到这一点。
检查包装错误列表中的值:
iferrors.Is(err,RecordNotFoundErr){//...}
检查特定类型(下面例子是来自标准库的网络错误):
varnerr*net.Erroriferrors.As(err,&nerr){//...(usenerrwhichisa*net.Error)}
以上总结了 Go 1.13 及更高版本中的错误包装。
Go 1.20 新特性让我们看看 Go 1.20 中真正的新功能,从函数errors.Join开始,它通过可变参数包装错误列表:
err1:=errors.New("err1")err2:=errors.New("err2")err:=errors.Join(err1,err2)fmt.Println(err)
当事先不知道错误数量时,此功能可用于将错误连接在一起。一个很好的例子是从 goroutines 收集错误。值得一提的是,该函数将列表中的错误与换行符连接起来。上面的代码片段打印:
err1err2
对于许多应用程序或(日志记录)库来说,这可能会存在问题,它们期望错误通常只是没有换行符的字符串。幸运的是,Go 1.20 中的另一个变化改变了fmt.Errorf的行为:该函数现在接受多个%w格式说明符:
err1:=errors.New("err1")err2:=errors.New("err2")err:=fmt.Errorf("%w+%w",err1,err2)fmt.Println(err)
以前会导致格式错误的格式字符串现在可以正确打印:
err1+err2
同时包装多个错误实现Unwrap() error,这是可能的吗?
事实证明,在 Go 1.20 标准库中有一种新的机制: 实现Unwrap() []error函数的错误类型可以包装多个错误。让我们来看看这是如何在库中实现的:
typejoinErrorstruct{errs[]error}func(e*joinError)Error()string{//concatenateerrorswithanewlinecharacter}func(e*joinError)Unwrap()[]error{returne.errs}
一个理论上的接口,但标准库中实际不存在,如下所示:
typeMultiWrappedErrorinterface{Unwrap()[]error}
由于 Go 不允许方法重载,因此每种类型都可以实现Unwrap() error或Unwrap() []error,但不能同时实现。还记得我提到过包装错误本质上是一个链表吗?实现前一个(新引入的)方法的类型实际上形成了一个链接树,函数errors.Is和errors.As的工作方式相同,只是现在它们需要遍历树而不是列表。根据文档,该实现执行预排序、深度优先遍历。
这确实是 Go 1.20 带来的全部,它可能看起来是一个小的变化,但它提供了如何有效和干净地处理错误的新方法。在展示真实示例之前,让我总结一下新功能:
新的Unwrap []error函数契约允许遍历错误树。
新的errors.Join函数,这是一个方便的函数,用于连接两个错误字符串值(使用换行符)。
现有函数errors.Is和errors.As已更新,可以同时处理错误列表和错误树。
现有函数fmt.Errorf现在接受多个%w格式动词。实践上面这一切都很棒,但是你如何在实践中利用它呢?
在一个小型 REST API 微服务中,我们通过errors.New和fmt.Errorf处理来自 DAO 包(数据库)、REST 客户端(其他后端服务)和其他包的各种错误。返回的 HTTP 状态代码应该是 2xx、4xx 或 5xx,具体取决于错误状态以遵循最佳 REST API 实践。实现此过程的一种方法是解开主 HTTP 处理程序中的错误并找出它是哪种错误。
然而,通过多重错误包装,现在可以包装根本原因(例如数据库返回 “no records found” )和返回给用户 HTTP 代码(在本例中为 404)。
一个工作示例如下所示:
packagemainimport("errors""fmt")//commonHTTPstatuscodesvarNotFoundHTTPCode=errors.New("404")varUnauthorizedHTTPCode=errors.New("401")//databaseerrorsvarRecordNotFoundErr=errors.New("DB:recordnotfound")varAffectedRecordsMismatchErr=errors.New("DB:affectedrecordsmismatch")//HTTPclienterrorsvarResourceNotFoundErr=errors.New("HTTPclient:resourcenotfound")varResourceUnauthorizedErr=errors.New("HTTPclient:unauthorized")//applicationerrors(thenewfeature)varUserNotFoundErr=fmt.Errorf("usernotfound:%w(%w)",RecordNotFoundErr,NotFoundHTTPCode)varOtherResourceUnauthorizedErr=fmt.Errorf("unauthorizedcall:%w(%w)",ResourceUnauthorizedErr,UnauthorizedHTTPCode)funchandleError(errerror){iferrors.Is(err,NotFoundHTTPCode){fmt.Println("Willreturn404")}elseiferrors.Is(err,UnauthorizedHTTPCode){fmt.Println("Willreturn401")}else{fmt.Println("Willreturn500")}fmt.Println(err.Error())}funcmain(){handleError(UserNotFoundErr)handleError(OtherResourceUnauthorizedErr)}
这将打印:
Willreturn404usernotfound:DB:recordnotfound(404)Willreturn401unauthorizedtocallotherservice:HTTPclient:unauthorized(401)
从这样的人工代码片段中可能看起来不太明显的是,实际上的错误声明通常分布在许多包中,并且不容易跟踪所有可能的错误以确保所需的 HTTP 状态代码。在这种方法中,所有在一个地方声明的应用程序级包装错误也包含了 HTTP 代码。
请注意,这在 Go 1.19 或更早版本中是不可能的,因为fmt.Errorf函数只会包装第一个错误。该代码确实在 1.19 上可以编译,甚至不会产生运行时恐慌,但它实际上不会工作。
显然,常见的 HTTP 状态代码很容易成为一种新的错误类型(基于int类型),因此可以通过errors.As轻松提取实际代码,但我想让示例保持简单。
Feel free to play around with the code on Go Playground. Make sure to use “dev branch” or 1.20+ version of Go. 可以在 Go Playground 上自由运行上述代码。确保使用 “dev branch” 或 Go 的 1.20+ 版本。现有应用在你的应用程序中实施新功能时,请注意errors.Unwrap函数。对于具有Unwrap() []error的错误类型,它总是返回nil:
err1:=errors.New("err1")err2:=errors.New("err2")err:=errors.Join(err1,err2)unwrapped:=errors.Unwrap(err)fmt.Println(unwrapped)
由于 Go 1.X 兼容性承诺,这会打印出 “nil”。当你引入多个包装错误时,请确保检查展开代码。幸运的是,典型 Go 代码中的大部分错误检查都是使用errors.Is和errors.As完成的。
错误包装并不是 Go 中所有错误处理的最终解决方案。它只是提供了一种干净的方法来处理典型 Go 应用程序中的错误,对于简单应用程序来说也许就完全足够了。原文地址:https://lukas.zapletalovi.com/posts/2022/wrapping-multiple-errors/原文作者:Lukáš Zapletal本文永久链接:https://github.com/gocn/translator/blob/master/2022/w50_Wrapping_multiple_errors译者:haoheipi校对:watermelo
往期推荐
谷歌发布查找开源漏洞的Go工具OSV-Scanner最好的Go框架:没有框架?
「每周译Go」如何在Go中构造For 循环想要了解Go更多内容,欢迎扫描下方关注公众号,回复关键词 [实战群],就有机会进群和我们进行交流
分享、在看与点赞Go
标签:
记者从中国铁路南昌局集团有限公司(以下简称南铁)获悉,2023年端午假
2023-06-15(原标题:问诊贷款直播)近期关于贷款直播的话题引发业内关
2023-06-156月15日消息,中信证券研报指出,6月12日,宁德时代发布重卡底盘换电解
2023-06-15大吉!海淀四季青大地块由越秀竞得,越秀,金源,顺义区,海淀区,四季青,建
2023-06-15“依山傍水,生命绿动”。近日,由中建深装参建的顺应山势而建的康复花
2023-06-15初夏时节,位于邢台市西部太行山深处的云梦山景区层峦叠嶂,碧水如镜,
2023-06-15富时指数又被叫做富时100指数,具体是指由富时集团编制的股票指数。富
2023-06-15央视网消息(新闻联播):神舟十六号航天员乘组已在轨半个月,目前空间
2023-06-15文 周菊2023年6月13日,由经济观察报主办的梦想照进现实——自动驾驶发
2023-06-151、霁红釉是清康熙仿明宣德的产品,釉色不像郎窑红浓艳,也不如豇豆红
2023-06-141、温州乔奴服饰有限公司2、乔奴服饰整合了优质的产品研发、服装设计生
2023-06-1401预约人群16-26岁女性;不限户籍;仅限首针在本门诊接种过的居民预约
2023-06-14当前大家对于氧化铁脱硫剂都是颇为感兴趣的,大家都想要了解一下氧化铁
2023-06-14近日,广东深圳。男子暴饮暴食熬夜引发急性胰腺炎。陈先生妻子表示:老
2023-06-142023年全国高考结束,各地转入高考阅卷工作。目前,全国各地陆续公布今
2023-06-14今年6月是全国第22个安全生产月。为进一步加强安全生产知识宣传教育,
2023-06-14记者14日从滨海新区获悉,作为滨海新区高质量发展支撑引领行动八大工程
2023-06-14每经AI快讯,有投资者在投资者互动平台提问:董秘您好,公司2022年半年
2023-06-14周口日报全媒体记者高洪驰6月14日,河南省“万人助万企”活动第16服务
2023-06-142、171开头的手机号属于哪个公司天津。3、171手机话费充值平台。4、171
2023-06-14红楼梦中有很多擅长伪装的人,说白了就是会演戏的人,贾府的关系比较复
2023-06-14InfinixNote30VIP于周二在全球发布。这是今年5月初推出的InfinixNote30系列的
2023-06-141、标准试块尺寸是:内径150mm,高150mm圆柱体试模。2、无侧限抗压强度
2023-06-14,今天小编给大家整理2023传奇手游排行榜,游戏里的传奇世界boss限时开
2023-06-1406月14日江苏地区关于皮棉的报价为17552元 吨。皮棉的规格:3128B
2023-06-14好声音学员刘雅婷发文悼念张恒远,他们多年前在深圳偶遇,成为好友,张
2023-06-14据央视新闻客户端报道:6月14日,国台办发言人朱凤莲主持例行新闻发布
2023-06-146月13日,圣元环保(300867)融资买入201 68万元,融资偿还156 81万元
2023-06-14国际权威学术出版商爱思唯尔深圳办公室6月13日在前海揭牌。深圳市前海
2023-06-14工商企业管理专业的主干课程主要有微观经济学、宏观经济学、会计学原理
2023-06-142023年以来,A股结构性行情加剧,部分押注赛道的绩优基金产品出现回撤
2023-06-14同花顺数据中心显示,青岛银行6月13日获融资买入332 55万元,占当日买
2023-06-14不打自招!普京:因为卡霍夫卡大坝被炸毁,乌军才无法在那里反攻,普京,
2023-06-141、帕斯卡1623年出生在法国一位数学家家庭,他三岁丧母,由担任着税务
2023-06-14今年4月,国家知识产权局确定10个城市(地区)为首批国家知识产权保护
2023-06-14上海国际电影电视节元宇宙体验路演中心在亚洲首个影视PLUS元宇宙Metafi
2023-06-14数据来源京东消费及产业发展研究院近年来,电子产品快速普及、使用频率
2023-06-14战胜国米之后,曼城队史首次赢得欧冠冠军,成为史上第八支加冕三冠王的
2023-06-14豆来为大家解答以上的问题。上海电视台纪实频道官网,上海电视台纪实频
2023-06-14番禺两宗地块触顶摇号收金23 27亿,番禺,摇号,涉宅,土拍,流拍,广州市,商
2023-06-14民生银行首席经济学家温彬表示,5月M2同比增速延续高位回落,主要受去
2023-06-136月13日,理想汽车官方微信公众号发文称,在刚刚过去的2023年第24周(6
2023-06-13首发4999元ROG掌机正式发售:媲美PS5性能3A大作无压力
2023-06-13作为西咸新区沣东新城先进制造产业园核心区主要道路,日前,天章三路正
2023-06-131、江苏美术省统考考哪些江苏的美术高考分数线是按文化和美术的总分计
2023-06-13每天取送装有金条的快递,他渐渐感觉不对劲了……,方圆杂志6月13日讯,
2023-06-13中国的发展不舍昼夜,不断向前,无论白天还是夜晚都充满活力。《活力夜
2023-06-1303:18“我的相机里、收藏柜里,终于有了中国产的大飞机!”——孙晓蒙
2023-06-13林心如带女儿拍摄慈善宣传片,林心如母女合体,女儿依旧未露脸!6月12日
2023-06-13对于丧茶是什么意思是什么这个问题感兴趣的朋友应该很多,这个也是目前
2023-06-13仰望U8:合二为一,开辟市场过去的中国汽车市场,一个本土品牌想要突破
2023-06-13央视网消息:6月13日,国家游泳中心发布紧急通知称,因场馆外围市政供
2023-06-13中国报告大厅2023年6月13日N-甲基吡咯烷酮价格最新走势监测显示:安徽
2023-06-131、地疗:标间480元 天(打折后280元 天)(地方)矿疗:标间480元 天
2023-06-13西强东弱?近25年总决赛西部球队17次夺冠西部总战绩为84胜56负,热火队,
2023-06-13高压快充概念13日盘中强势拉升,和顺电气“20cm”涨停,迦南智能涨约15
2023-06-131、多数是数据线或者设置问题。2、删除所有打印任务,关闭打印机电源,
2023-06-131、病情分析:最近是否有胸部外伤或最近一周有呼吸道感染史。2、一般胸
2023-06-132023年06月13日(星期二),中国养猪网猪价系统数据监测如下:生猪(品
2023-06-13市委副书记、市长龚正昨天主持召开市政府常务会议,要求按照市委部署,
2023-06-131、尽管专业的OCR文字识别电脑端软件很多,手机APP也不少,但如果你想
2023-06-13来源:密探财经(ID:SpyFinance)“宏达系”的陨落,似乎跟“金融玩砸
2023-06-13IT之家6月13日消息,消息人士昨日向路透社透露称,欧盟反垄断监管机构
2023-06-13今年以来,发行债券成为券商机构重要的补充流动性的方式之一。Wind数据
2023-06-13带全尺寸备胎的车型有:长城C50、北京现代悦动(参数|询价)、东风标致30
2023-06-13第一时间提供各大券商研究所报告,最大程度减少个人投资者与机构之间信
2023-06-13罗云峰与长三角聚劲科创大赛嘉宾代表举行工作会谈
2023-06-131、压力容器安全操作规程(需上墙悬挂)一.总则1.压力容器操作人员必
2023-06-13北京时间6月12日深夜,巴黎传来消息:经联合国教科文组织人与生物圈计
2023-06-13先把两根细线依次穿进针孔里,之后让那两根线长短对折,而不是相等对折,
2023-06-13很多女性都知道哪种款式更适合自己。尖尖的细高跟鞋也可以搭配出精致的
2023-06-131、宁远一中:永州市重华北路8号宁远二中:九嶷中路133号宁远三中:重
2023-06-12大家好,今日关于【5月网约车行业运行情况公布】的话题登上了各大平台
2023-06-12近日,中集安瑞科旗下中集太平洋海工与液化气船船东AvanceGas,签订2+2
2023-06-121、智能马达控制器,适用于额定电压至AC690V、额定电流至AC800A、额定
2023-06-12工伤职工停工留薪期是指职工因工作遭受事故伤害或者患职业病后,需要暂
2023-06-12每年一度的“618”作为家电产品销售旺季,也是电视升级换代的最佳时机
2023-06-1256岁阿姨很豪爽,相亲当天就同居,第二天起床直呼自己太年轻,红娘,医生
2023-06-126月8日灞桥区“灞水英才荟”系列公开课第二期——“集智聚力展拳脚惠企
2023-06-122023年湖北省十堰市茅箭区面向全国公开招聘高层次人才报名已结束,根据
2023-06-12南宁6月11日电(记者吴思思)记者从广西壮族自治区粮食和物资储备局获
2023-06-12A股三大股指6月12日集体低开后,指数继续分化。早盘沪弱深强格局再现,
2023-06-12摘要:2023年06月12日新华制药(000756)主力资金净流入253 16万元,占
2023-06-12相信不少小伙伴都对漫威在20年有何计划都很是期待,因为在很早的时候,
2023-06-12REITs场内份额限售总量327,719,955份,除了GLP普洛斯资本投资4号香港有
2023-06-121、康德自诩他在哲学上做了一个“哥白尼式的革命”,就是说他在哲学上
2023-06-12根据刑法规定,构成对单位行贿罪的,处三年以下有期徒刑或拘役。单位犯
2023-06-12没有绿拇指?不用担心。你带回家的每一株新植物都不会在几周内死去。让
2023-06-12该校教员吴玲指导学员开展实验。
2023-06-12近日,地处大围山腹地浏阳市张坊镇道官冲非遗活态传承山村,逐渐热闹起
2023-06-116月,中原大地遍野金黄,田间地头一片繁忙收获景象。近日,河南宝丰县4
2023-06-11“蔚来预计二季度营收、车辆交付量均下降。”
2023-06-11《说史记:小说一样的历史》杨早 著后浪|北京联合出版公司鲁迅在《中国
2023-06-11来为大家解答以上的问题。黑天鹅蛋糕官网价格表,黑天鹅蛋糕这个很多人
2023-06-111、严格来说。2、八门之中。3、杜门是不属于吉门。本文就为大家分享到
2023-06-111、原料:金桂、白糖、米酒或高梁酒、桂园肉和十克白参、一百克红枣。2
2023-06-11新京报讯(记者王子扬)2023北京国际茶业展、北京马连道国际茶文化展、
2023-06-111、般说来论胸部罩杯大小正常乳晕直径3-5公分颜色粉红色乳晕随着青春期
2023-06-11新华社北京6月9日电(记者刘羽佳)证监会官网9日发布消息,为健全资本市
2023-06-11Copyright © 2015-2022 南极水产网版权所有 备案号:粤ICP备2022077823号-13 联系邮箱: 317 493 128@qq.com