范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

Golang中更好的错误处理理论和实践技巧

  云和安全管理服务专家新钛云服 张春翻译编程语言应该如何处理错误?例如,打开具有给定名称的文件并将其读取到缓冲区的函数可能由于多种原因而失败:文件可能不存在,打开的程序可能没有打开它的权限,或者它可能太大而无法容纳 缓冲区;大多数语言都使用异常:抛出的异常通过调用堆栈传播直到在 try-catch 块中处理的级别。异常模型将错误视为特殊情况,与程序的常规返回值流程分开处理。
  这种方法有几个缺点。首先,它可以对程序员隐藏错误处理路径,特别是在捕获异常不是强制性的情况下,例如在 Python 中。即使在具有必须处理的 Java 风格的检查异常的语言中,如果在与原始调用不同的级别上处理错误,也并不总是很明显错误是从哪里引发的。
  我们都见过长长的代码块包装在一个 try-catch 块中。在这种情况下,catch 块实际上充当 goto 语句,这通常被认为是有害的(奇怪的是,C 中的关键字被认为可以接受的少数用例之一是错误后清理,因为该语言没有 Golang- 样式延迟语句)。
  如果你确实从源头捕获异常,你会得到一个不太优雅的 Go 错误模式版本。这可能会解决混淆代码的问题,但会遇到另一个问题:性能。在诸如 Java 之类的语言中,抛出异常可能比函数的常规返回慢数百倍。
  Java 中最大的性能成本是由打印异常的堆栈跟踪造成的,这是昂贵的,因为运行的程序必须检查编译它的源代码 。仅仅进入一个 try 块也不是空闲的,因为需要保存 CPU 内存寄存器的先前状态,因为它们可能需要在抛出异常的情况下恢复。
  如果您将异常视为通常不会发生的异常情况,那么异常的缺点并不重要。这可能是传统的单体应用程序的情况,其中大部分代码库不必进行网络调用——一个操作格式良好的数据的函数不太可能遇到错误(除了错误的情况)。一旦您在代码中添加 I/O,无错误代码的梦想就会破灭:您可以忽略错误,但不能假装它们不存在!
  try {
  doSometing()
  } catch (IOException e) {
  // ignore it
  }
  与大多数其他编程语言不同,Golang 接受错误是不可避免的。如果在单体架构时代还不是这样,那么在今天的模块化后端服务中,服务通常和外部 API 调用、数据库读取和写入以及与其他服务通信 。
  以上所有方法都可能失败,解析或验证从它们接收到的数据(通常在无模式 JSON 中)也可能失败。Golang 使可以从这些调用返回的错误显式化,与普通返回值的等级相同。从函数调用返回多个值的能力支持这一点,这在大多数语言中通常是不可能的。Golang 的错误处理系统不仅仅是一种语言怪癖,它是一种将错误视为替代返回值的完全不同的方式!
  重复 if err != nil
  对 Go 错误处理的一个常见批评是被迫重复以下代码块:
  res, err := doSomething()
  if err != nil {
  // Handle error
  }
  对于新用户来说,这可能会觉得没用而且浪费行数:在其他语言中需要 3 行的函数很可能会增长到 12 行 :
  这么多行代码!这么低效!如果您认为上述内容不优雅或浪费代码,您可能忽略了我们检查代码中的错误的全部原因:我们需要能够以不同的方式处理它们!对 API 或数据库的调用可能会被重试。
  有时事件的顺序很重要:调用外部 API 之前发生的错误可能不是什么大问题(因为数据从未通过发送),而 API 调用和写入本地数据库之间的错误可能需要立即注意,因为 这可能意味着系统最终处于不一致的状态。即使我们只想将错误传播给调用者,我们也可能希望用失败的解释来包装它们,或者为每个错误返回一个自定义错误类型。
  并非所有错误都是相同的,并且向调用者返回适当的错误是 API 设计的重要部分,无论是对于内部包还是 REST API 。
  不必担心在你的代码中重复 if err != nil ——这就是 Go 中的代码应该看起来的样子。
  自定义错误类型和错误包装
  从导出的方法返回错误时,请考虑指定自定义错误类型,而不是单独使用错误字符串。字符串在意外代码中是可以的,但在导出的函数中,它们成为函数公共 API 的一部分。更改错误字符串将是一项重大更改——如果没有明确的错误类型,需要检查返回错误类型的单元测试将不得不依赖原始字符串值!事实上,基于字符串的错误也使得在私有方法中测试不同的错误案例变得困难,因此您也应该考虑在包中使用它们。回到错误与异常的争论,返回错误也使代码比抛出异常更容易测试,因为错误只是要检查的返回值。不需要测试框架或在测试中捕获异常 。
  可以在 database/sql 包中找到简单自定义错误类型的一个很好的示例。它定义了一个导出常量列表,表示包可以返回的错误类型,最著名的是 sql.ErrNoRows。虽然从 API 设计的角度来看,这种特定的错误类型有点问题(您可能会争辩说 API 应该返回一个空结构而不是错误),但任何需要检查空行的应用程序都可以导入该常量并在代码中使用它不必担心错误消息本身会改变和破坏代码。
  对于更复杂的错误处理,您可以通过实现返回错误字符串的 Error() 方法来定义自定义错误类型。自定义错误可以包括元数据,例如错误代码或原始请求参数。如果您想表示错误类别,它们很有用。DigitalOcean 的本教程展示了如何使用自定义错误类型来表示可以重试的一类临时错误。
  通常,错误会通过将低级错误与更高级别的解释包装起来,从而在程序的调用堆栈中传播。例如,数据库错误可能会以下列格式记录在 API 调用处理程序中:调用 CreateUser 端点时出错:查询数据库时出错:pq:检测到死锁。这很有用,因为它可以帮助我们跟踪错误在系统中传播的过程,向我们展示根本原因(数据库事务引擎中的死锁)以及它对更广泛系统的影响(调用者无法创建新用户)。
  自 Go 1.13 以来,此模式具有特殊的语言支持,并带有错误包装。通过在创建字符串错误时使用 %w 动词,可以使用 Unwrap() 方法访问底层错误。除了比较错误相等性的函数 errors.Is() 和 errors.As() 外,程序还可以获取包装错误的原始类型或标识。这在某些情况下可能很有用,尽管我认为在确定如何处理所述错误时最好使用顶级错误的类型。
  Panics
  不要 panic()!长时间运行的应用程序应该优雅地处理错误而不是panic。即使在无法恢复的情况下(例如在启动时验证配置),最好记录一个错误并优雅地退出。panic比错误消息更难诊断,并且可能会跳过被推迟的重要关闭代码。
  Logging
  我还想简要介绍一下日志记录,因为它是处理错误的关键部分。通常你能做的最好的事情就是记录收到的错误并继续下一个请求。
  除非您正在构建简单的命令行工具或个人项目,否则您的应用程序应该使用结构化的日志库,该库可以为日志添加时间戳,并提供对日志级别的控制。最后一部分特别重要,因为它将允许您突出显示应用程序记录的所有错误和警告。通过帮助将它们与信息级日志分开,这将为您节省无数时间。
  微服务架构还应该在日志行中包含服务的名称以及机器实例的名称。默认情况下记录这些时,程序代码不必担心包含它们。您也可以在日志的结构化部分中记录其他字段,例如收到的错误(如果您不想将其嵌入日志消息本身)或有问题的请求或响应。只需确保您的日志没有泄露任何敏感数据,例如密码、API 密钥或用户的个人数据!
  对于日志库,我过去使用过 logrus 和 zerolog,但您也可以选择其他结构化日志库。如果您想了解更多信息,互联网上有许多关于如何使用这些的指南。如果您将应用程序部署到云中,您可能需要日志库上的适配器来根据您的云平台的日志 API 格式化日志 - 没有它,云平台可能无法检测到日志级别等某些功能。
  如果您在应用程序中使用调试级别日志(默认情况下通常不记录),请确保您的应用程序可以轻松更改日志级别,而无需更改代码。更改日志级别还可以暂时使信息级别甚至警告级别的日志静音,以防它们突然变得过于嘈杂并开始淹没错误。您可以使用在启动时检查以设置日志级别的环境变量来实现这一点。
  原文:https://levelup.gitconnected.com/better-error-handling-in-golang-theory-and-practical-tips-758b90d3f6b4

新手买相机到底要注意哪些?相机到底玩什么拍照是一种乐趣,出片是结果不是过程很多人买相机是为了生活中添加一些乐趣而不是为了拍照卖钱所以不要盲目的追求过剩的性能而放弃了体验这个过程包括什么1相机颜值2相机操控握新手小白预算3K5K,有哪些值得入手的微单?很多刚接触摄影的小伙伴,都想选购一台心仪的相机。但是预算不多,又要镜头机身都具备选购一款入门相机,之后再慢慢扩充,更多数码宝贝们那预算35K,都有哪些微单可选择呢?想入手入门微单相联想TruScale服务一个内生外化的故事文路易曹惺璧智能化时代,所有行业都值得重做一遍。作为智能化时代的基础,解决方案和服务有什么理由不去创新和改变呢?某大型新零售企业将一款交互式智能货架设备运用于线下门店,从而更好地实从韦东奕看天才的养成保护比培育更重要曹惺璧文高考前后,北大数学系助理教授韦东奕的一段受访视频火遍全网。视频中,他身穿一件普普通通的黑衬衫,怀抱矿泉水瓶,手拎着刚从食堂买来的三个馒头,回答记者的问题简单而质朴。然而,在外婆家饥饿营销提升顾客购买欲这是令人脑洞大开的8个营销案例系列的最后一篇。企业进行饥饿营销需要具备三个前提一是产品要具有不可替代性二是消费者心态不够成熟,愿意追逐新奇和稀缺三是市场竞争不激烈。文路易饥饿营销主非菲律宾人如何看待菲律宾人?在菲律宾生活了一年多之后,以下是我的观察1可能是这个星球上最快乐和最乐观的人。2他们与家人关系很密切。对他们来说,家庭不仅仅意味着父母,还意味着他们的堂兄弟姐妹叔叔和阿姨每个人都是拉姆查兰成功的公司治理需要CEO与首席董事密切配合首席董事管的是董事会,而CEO管的是企业。首席董事可以帮助CEO在董事会上沟通解决公司管理中的问题,CEO可以充分利用首席董事的人脉关系和专业能力,两者的密切配合会在公司治理中起到手机进化史,盘点那些已经消失的功能随着手机科技的不断更迭换代,出现了越来越多新的功能,但同时的,也有很多消失的功能,在那些消失的功能里,你最舍不得哪个?第一个呼吸灯这个是我最舍不得的一个功能,它可以息屏的情况下,通盘点吴亦凡代言过的小米手机,你都换了吗?近日,多个品牌与吴亦凡解约,在前些年吴亦凡代言过很多手机,仔细地查看了一下,大约九部手机。其中一些手机的口碑及质量方面都还不错,你用过这几部手机吗?小米8在2018年发布,因为当时这些潜在钉子户手机,你了解几部?基于数码产品更新换代的速度,相信很多小伙伴都抱着买新不买老的心态,这与是千元的性价比产品还是价格较高的旗舰产品无关。而说到钉子户手机,除了iPhone6s小米6等,还有这几款潜力股十年前最火的三部手机,你用过哪一部?说起十年前的手机,你脑海中的第一印象是什么?漫天的按键机?没有wifi,微信,没有短视频。就连QQ都还是在那种老式的台式电脑上才可以用,大家还在用着按键机,靠着短信社交。2021年
设计模式10模板方法模式模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特殊步骤。模板方法模式通过把不变行为搬移到父类,父类4月份CPI数据出炉猪肉价格环比再降7。6消费价格指数同比涨幅进一步回落,时隔6个月重回3时代。中泰证券梁中华吴嘉璐也表示,往前看CPI继续下行,下半年大概率转负。主要原因在于,猪肉价格连续下降,食品价格逐漸回落而非食品和川普被华为打得措手不及,鸿蒙系统终于来了?所有国内厂商沸腾了现如今川普对包括华为在内的各大国有企业正在进行所谓制裁,尤其是最近的腾讯和字节跳动,更是闹得沸沸扬扬,但是就在他洋洋得意之时,华为又传出好消息,着实让川普措手不及。就在最近,行业分30岁,奋斗的沪漂王漫妮缺的是一套房吗?大家好,我是老李。一台饮水机一百元,我只拥有一个饮水泵,让人负担不起的不是价格,是带着它们一起搬家。相信这句王漫妮的台词让无数观看三十而已的朋友们记忆深刻。月薪2万,没有房你在大城重疾险这也不赔那也不赔,到底还要不要买?大家好,我是老李。最近,老李我在网上看到不少文章指出重疾险的理赔条件太苛刻了!因此,在相应的文章下的评论中有不少如此这样的回帖重疾险理赔也太难吧,这也不赔那也不赔!重疾险这么难赔,股权代持的隐忧,李国庆俞渝为夺权再开战大家好,我是老李。2020年的大瓜庆余年还在继续先是抢夺公章争权夺势,然后再是因送蘑菇认定还有感情,所以无法离婚,昨天又来了第三集庆余年夺权大战亮底牌,儿子告父母8月9日晚,非常喜基金经理为什么钟情3。5的收益率?最近我有一位男性客户,基金经理(YFD基金),咨询我之后买了一份年复利率3。5的年金险,每年交50万,一共交5年,非常简单的产品第七年,本息和一共275。5万(相当于25。5万的利潘玮柏官宣结婚,但我更羡慕他年入上亿的副业大家好,我是老李。2020年7月27日,40岁的台湾籍歌手潘玮柏突然官宣结婚,伴侣是一名90后空姐。突如其来的婚讯已经是明星的常态了,但还是让网络掀起一阵八卦,好在曾经的荧幕情侣吴股价爆发后,特斯拉开启保险业务大家好,我是老李。今天我又来聊聊老朋友特斯拉。特斯拉超级工厂要卖保险?今年特斯拉在股市的行情一路高歌猛进,今年股价最高曾达到1794。53美元股。在连续完成四个季度的盈利目标后,特我们不是命中注定要住如此昂贵的房子大家好,我是老李。万科地产的郁亮在有一次考察完日本的房地产市场后问过这么一个问题为什么在日本东京,即使距离市中心通勤时间有一小时,房价只有1万多一平米,半小时的话也就2,3万?通勤马云退休,黄峥卸任拼多多,2020年大佬们为何纷纷退出?大家好,我是老李。2020年的疫情让整个世界都变得异常敏感,这种敏感投射到股市中,今年以来,阿里巴巴腾讯拼多多等互联网龙头股价频频创新高,但其创始人却接连减持。富豪榜不断被刷新的背