GO语言学习笔记(与Java的比较学习)(十)

错误处理与测试

Go 没有像 Java 和 .NET 那样的 try/catch 异常机制:不能执行抛异常操作。但是有一套 defer-panic-and-recover 机制

错误处理

Go 有一个预先定义的 error 接口类型

type error interface {Error() string
}

errors 包中有一个 errorString 结构体实现了 error 接口。当程序处于错误状态时可以用 os.Exit(1) 来中止运行。

定义错误

任何时候当你需要一个新的错误类型,都可以用 errors(必须先 import)包的 errors.New 函数接收合适的错误信息来创建,像下面这样:

err := errors.New(“math - square root of negative number”)

包也可以用额外的方法(methods)定义特定的错误,比如 net.Error:

package net
type Error interface {Timeout() bool   // Is the error a timeout?Temporary() bool // Is the error temporary?
}

用 fmt 创建错误对象

通常你想要返回包含错误参数的更有信息量的字符串,例如:可以用 fmt.Errorf() 来实现:它和 fmt.Printf () 完全一样,接收有一个或多个格式占位符的格式化字符串和相应数量的占位变量。和打印信息不同的是它用信息生成错误对象。

比如在前面的平方根例子中使用:

if f < 0 {return 0, fmt.Errorf("math: square root of negative number %g", f)
}

运行时异常和 panic

当发生像数组下标越界或类型断言失败这样的运行错误时,Go 运行时会触发运行时 panic,伴随着程序的崩溃抛出一个 runtime.Error 接口类型的值。这个错误值有个 RuntimeError() 方法用于区别普通错误。

panic 可以直接从代码初始化:当错误条件(我们所测试的代码)很严苛且不可恢复,程序不能继续运行时,可以使用 panic 函数产生一个中止程序的运行时错误。panic 接收一个做任意类型的参数,通常是字符串,在程序死亡时被打印出来。Go 运行时负责中止程序并给出调试信息。

package main
​
import "fmt"
​
func main() {fmt.Println("Starting the program")panic("A severe error occurred: stopping the program!")fmt.Println("Ending the program")
}

从 panic 中恢复(Recover)

正如名字一样,这个(recover)内建函数被用于从 panic 或 错误场景中恢复:让程序可以从 panicking 重新获得控制权,停止终止过程进而恢复正常执行。

recover 只能在 defer 修饰的函数中使用:用于取得 panic 调用中传递过来的错误值,如果是正常执行,调用 recover 会返回 nil,且没有其它效果。

总结:panic 会导致栈被展开直到 defer 修饰的 recover () 被调用或者程序中止

这跟 Java 和 .NET 这样的语言中的 catch 块类似。 log 包实现了简单的日志功能:默认的 log 对象向标准错误输出中写入并打印每条日志信息的日期和时间。除了 Println 和 Printf 函数,其它的致命性函数都会在写完日志信息后调用 os.Exit (1),那些退出函数也是如此。而 Panic 效果的函数会在写完日志信息后调用 panic;可以在程序必须中止或发生了临界错误时使用它们,就像当 web 服务器不能启动时那样

自定义包中的错误处理和 panicking

这是所有自定义包实现者应该遵守的最佳实践:

1)在包内部,总是应该从 panic 中 recover:不允许显式的超出包范围的 panic ()

2)向包的调用者返回错误值(而不是 panic)。

启动外部命令和程序

os 包有一个 StartProcess 函数可以调用或启动外部系统命令和二进制可执行文件;它的第一个参数是要运行的进程,第二个参数用来传递选项或参数,第三个参数是含有系统环境基本信息的结构体。

这个函数返回被启动进程的 id(pid),或者启动失败返回错误

Go 中的单元测试和基准测试

_test 程序不会被普通的 Go 编译器编译,所以当放应用部署到生产环境时它们不会被部署;只有 gotest 会编译所有的程序:普通程序和测试程序。

测试文件中必须导入 "testing" 包,并写一些名字以 TestZzz 打头的全局函数,这里的 Zzz 是被测试函数的字母描述,如 TestFmtInterface,TestPayEmployees 等。

测试的编写规则:

Go 的测试必须按规则方式编写,不然 go test 将无法正确定位测试代码的位置,主要三点规则。

首先,测试代码文件的命名必须是以 _test.go 结尾,比如上节中的文件名 math_tesh.go 并非随意取的。

还有,代码中的用例函数必须满足匹配 TestXxx,比如 TestAbs。

关于 Xxx,简单解释一下,它主要传达两点含义,一是 Xxx 表示首个字符必须大写或数字,简单而言就是可确定单词分隔,二是首字母后的字符可以是任意 Go 关键词合法字符,如大小写字母、下划线、数字。

测试函数必须有这种形式的头部:

func TestAbcde(t *testing.T)

T 是传给测试函数的结构类型,用来管理测试状态,支持格式化测试日志,如 t.Log,t.Error,t.ErrorF 等。在函数的结尾把输出跟想要的结果对比,如果不等就打印一个错误。成功的测试则直接返回。

用下面这些函数来通知测试失败:

1)func (t *T) Fail()

标记测试函数为失败,然后继续执行(剩下的测试)。

2)func (t *T) FailNow()

标记测试函数为失败并中止执行;文件中别的测试也被略过,继续执行下一个文件。

3)func (t *T) Log(args ...interface{})

args 被用默认的格式格式化并打印到错误日志中。

4)func (t *T) Fatal(args ...interface{})

结合 先执行 3),然后执行 2)的效果。
package even
​
import "testing"
​
func TestEven(t *testing.T) {if !Even(10) {t.Log(" 10 must be even!")t.Fail()}if Even(7) {t.Log(" 7 is not even!")t.Fail()}
​
}
​
func TestOdd(t *testing.T) {if !Odd(11) {t.Log(" 11 must be odd!")t.Fail()}if Odd(10) {t.Log(" 10 is not odd!")t.Fail()}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/718034.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十二、类与声明

类与声明 什么是类&#xff1f; 前情总结 前面22讲的课基本上就做了两件事 学习C#的基本元素学习类的成员 析构函数&#xff1a; 当对象不再被引用的时候&#xff0c;就会被垃圾回收器gc&#xff0c;回收。而收回的过程当中&#xff0c;如果需要做什么事情&#xff0c;就放在…

远程调用--Http Interface

远程调用--Http Interface 前言1、导入依赖2、定义接口3 创建代理&测试4、创建成配置变量 前言 这个功能是spring boot6提供的新功能&#xff0c;spring允许我们通过自定义接口的方式&#xff0c;给任意位置发送http请求&#xff0c;实现远程调用&#xff0c;可以用来简化…

已解决org.springframework.dao.DataRetrievalFailureException数据检索失败异常的正确解决方法,亲测有效!!!

已解决org.springframework.dao.DataRetrievalFailureException数据检索失败异常的正确解决方法&#xff0c;亲测有效&#xff01;&#xff01;&#xff01; 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 总结 在使用Spring Framework进行数据库操作时&…

关于硅金属电阻器?

EAK金属硅电阻器类似于陶瓷复合电阻器&#xff0c;在脉冲负载方面具有优势&#xff0c;需要高峰值功率或高电压与低电感&#xff08;如预充电电路&#xff09;的组合。硅金属电阻器具有更高的连续额定温度&#xff0c;为 350C&#xff0c;而陶瓷电阻器为 250C。这种扩展的温度范…

[蓝桥杯 2023 省 B] 冶炼金属

P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 参考题解&#xff1a; #C3150——蓝桥杯2023年第十四届省赛真题-冶炼金属(分块)-Dotcpp编程社区 https://www.bilibili.com/video/BV1wc411x7KU/?spm_id_from333.1007.top_right_bar_windo…

RT-Thread操作系统 串口DMA接收时数据被拆分多包

一、问题现象 在使用RT Thread操作系统&#xff0c;串口DMA接收数据时&#xff0c;通过log打印发现&#xff0c;例如GPS NEMA数据一包数据量较大或者时&#xff0c;接收到的数据被拆分多包处理&#xff1b; 二、问题解决方案 修改DMA驱动程序 在drivers/drv_usart.c中屏蔽如…

板子合集1.0

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 原文链接&#xff1a;https://blog.csdn.net/JK01WYX/ 文章目录 1.快速幂板子2.gcd得最大公约数3.堆优化的dijkstra板子4.线段树1板子 区间加线段…

中缀表达式转换逆波兰式(后缀表达式)

算法思路来自于王道的数据结构 #include <iostream> #include <stack> #include <map>using namespace std; string eq; stack<char> op; string rst ""; map<char, int> dict;// 获取优先级 int getPrio(char op) {if (op )return …

【Dubbo专栏 01 】深入探索:dubbo的架构是什么?

文章目录 Dubbo&#xff1a;深入解析分布式服务框架的核心概念与实现01 Dubbo简介02 Dubbo核心概念2.1 服务提供者&#xff08;Provider&#xff09;2.2 服务消费者&#xff08;Consumer&#xff09;2.3 注册中心&#xff08;Registry&#xff09;2.4 负载均衡&#xff08;Load…

如何对用OpenCV开发的API进行测试 (Google Test 版本)

如何对用OpenCV开发的API进行测试 &#xff08;Google Test 版本&#xff09; 如何对用OpenCV开发的API进行测试断言介绍断言基础的断言数值比较字符串比较 如何对用OpenCV开发的API进行测试 假设你想测试一个使用OpenCV开发的图像处理API&#xff0c;例如一个图像滤波函数。以…

SWC Runnable

runnable概念 runnable是编写应用程序行为逻辑的 SWC 的一部分。Runnable 类似于 C 中的函数,类似RTOS中的task,程序运行的实体,swc的灵魂。在 AUTOSAR 中,我们在配置期间在 SWC 中创建 Runnable,并且 在 SWC 的相应源文件中生成Runnable 或函数骨架。骨架函数的名称与我…

【硬件工程师面经整理15_低通/高通/带通滤波器】

低通/高通/带通滤波器 1.1 低通滤波器1.2 高通滤波器1.3 带通滤波器 1.1 低通滤波器 【定义】电感阻止高频信号通过而允许低频信号通过&#xff0c;电容的特性却相反。信号能够通过电感的滤波器、或者通过电容连接到地的滤波器对于低频信号的衰减要比高频信号小&#xff0c;称…

第二篇【传奇开心果系列】Python的自动化办公库技术点案例示例:深度解读Pandas金融数据分析

传奇开心果博文系列 系列博文目录Python的自动化办公库技术点案例示例系列 博文目录前言一、Pandas 在金融数据分析中的常见用途和功能介绍二、金融数据清洗和准备示例代码三、金融数据索引和选择示例代码四、金融数据时间序列分析示例代码五、金融数据可视化示例代码六、金融数…

软考高级:DNS欺骗相关知识和例题

一、AI 解析 DNS欺骗&#xff0c;又称DNS缓存投毒&#xff0c;是一种网络攻击技术。攻击者通过篡改DNS服务器的缓存数据&#xff0c;使得DNS查询的结果指向一个恶意的IP地址&#xff0c;从而引导用户访问到钓鱼网站或者恶意软件下载页面&#xff0c;对用户的信息安全造成威胁。…

后台组件-IO定义

<groupId>org.qlm</groupId><artifactId>qlm-io</artifactId><version>1.0-SNAPSHOT</version> 该组件定义了前端和后台微服务直接通讯结构以及返回值定义。 RequestInfo&#xff1a;请求结构 ResponseResult&#xff1a;非分页的返回结…

最新版风车IM通讯iosapph5三端源码及视频教程

最新版风车IM通讯iosapph5三端源码及视频教程 1.宝塔环境如下: Nginx 1.20 Tomcat 8 MySQL 8.0 Redis 7 2.放行端口如下&#xff1a; 666 6600 6700 7000&#xff08;用作前端&#xff09; 7001&#xff08;用作后端&#xff09; 3.宝塔数据库添加数据库旁边有个ro…

Sqli-labs靶场第21、22关详解[Sqli-labs-less-21、22]自动化注入-SQLmap工具注入|sqlmap跑base64加密

Sqli-labs-Less-21、22 由于21/22雷同&#xff0c;都是需要登录后&#xff0c;注入点通过Cookie值进行测试&#xff0c;值base64加密 修改注入数据 选项&#xff1a;--tamperbase64encode #自动化注入-SQLmap工具注入 SQLmap用户手册&#xff1a;文档介绍 - sqlmap 用户手册 由…

MySql行子查询

目录 行子查询数据准备 行子查询 子查询返回的结果是一行(可以是多列)&#xff0c;这种子查询称为行子查询。 常用的操作符&#xff1a; 、<> 、IN 、NOT IN 案例&#xff1a;查询与"韦一笑"的入职日期及职位都相同的员工信息 可以拆解为两步进行&#xff1…

框架漏洞-->Struts2 Docker_Vulnhub搭建

来浅浅的讲一下Struts2漏洞 目录 1.Docker_Vulnhub搭建 2.Struts2 3.Struts2的框架特征 4.S2-029-->Remote Code Execution 5.漏洞复现 1.RCE 2.Getshell 1.Docker_Vulnhub搭建 因为我用的是Linux&#xff0c;所以我选择直接搭个docker&#xff0c;这里我建议先换个…

在Ubuntu22.04安装Fcitx5中文输入法教程(十分详细)

前言 书接上回&#xff0c;一时兴起将主力机的 Ubuntu 20.04 LTS 升级至了刚刚发布的 22.04 LTS。从 X 切换到 Wayland 、GNOME 从 3.36 升级至 42、Python 默认为 3.10 等等……使用太新的软件包反而暂时带来了麻烦&#xff0c;部分原有的软件和插件都不可用了。这其中就包括…