昨天我们已经了解了go函数部分,接下来我们继续来看下函数剩下的部分,若昨天所述,我们应当在学习中保持空杯心态,不浮躁不焦虑,看了不一等会,但是看了,能够总结,并且以博文的方式表达出来,这应该才是学了,加油哦,运维小学生。
变长参数
什么是变长参数
函数在调用的时候有可变的参数,这个就被称之为变长函数。
还记得,我们使用输出语句么?它就可以接收多个参数。
mainStart := time.Now() ... fmt.Println("主函数运行了: " , time.Since(mainStart))
我们可以看到,上述 fmt.Println("主函数运行了: " , time.Since(mainStart))函数中调用了多个参数变量,我们可以切进去看下
发现参数是 a ...interface{} ,所以这个也被称为变长参数,我们调用有这个类型的函数的时候,可以传递任何参数
其实这个参数传进去的是切片,我们可以一下例子来看下
我们执行下
变长参数有什么用
我们可以来写这样一个经典的案例,定义一个函数,传入2各值: a、b,我们返回一个最大值
以上例子,我们很快就写出来了。我们执行下
如果后期修改需求,有3个参数,5个参数,n个参数呢? 我们要定义n个函数来处理么?
我们可以使用变长参数,例如,我们修改下代码
我们执行查看下
可以看到,我们正常返回了,没有问题的
我们假如已经存在了一个slice,我们如何调用呢? 我们只需要在后面加一个省略号,即可调用,即: f1(slice1...)
panic
panic简单案例
我们来编写一个程序,其中定义一个切片,我们访问一下切片外的数据,模拟越界
我们执行下
我们看到抛错了,一般而言,go panic 会打印出 某个函数调用的语句,我们可以根据信息,来检测程序问题,而panic语句后的代码,将不会被执行了。
go 为什么使用panic
一开始看到panic的时候,我觉得很神奇,对于目前现在的编程语言,类似c++、python、java其实都有处理异常机制,那就是try-catch, 而为什么go需要自己来获取错误呢? 之所以go不提供try-catch,是因为这会让程序变得复杂,所以不提供,但是Go提供了另外一个函数,那就是recover
执行panic后发送了什么
当我们程序panic后,程序会停止,不会执行下面的语句,若我们之前定义了defer语句,则defer语句会被执行,且程序异常后会打印出问题的信息,供开发者查看
我们举个例子
我们按照上述的意思,若panic之后,下列语句就不执行了,我们来看下
从结果,可知,的确是这样的。
recover
在panic后,我们可以使用recover来恢复程序,recover需要写在defer中,因为它在程序结尾处运行,还记得上一节提到的go中为什么没有try-catch么,go使用recover的意义是在于让我们来判断该panic是否是我们预想的,若是我们预想的,那么我们可以像普通函数一样来处理该panic,若不是的话,则我们的确需要来触发panic。
我们可以通过例子来说明
我们编写一个读取josn配置文件的程序,当文件不存在时,我们使用recover恢复一下,当使用json.Unmarshal解析失败时,我们认为此函数异常,则抛出panic
我们先看下,不添加recover,正常逻辑的程序的输出
我们定义conf.json
我们运行程序
我们来修改下程序
增加如下语句
defer func() { perr := recover() switch perr.(type) { case *os.PathError: // os.open错误 fmt.Println("error: ", conf, "未找到") case *json.UnmarshalTypeError: // json.Unmarshal错误 panic(fmt.Sprintf("%s , %v", "自定义 panic json UnmarshalTypeError", perr)) } }()
这里,我们使用断言,来判断,到底是 os.open错误 还是 json.Unmarshal错误 ,好的,我们来模拟下
我们将conf.json 改一下名称,再次执行程序
这里并没有抛panic,应该说,这里抛了panic,被我们给恢复了,
我们再试试让json解析失败呢
我们只需要将 server_id给调整的大一些,让其溢出即可
我们再尝试一下程序
这里就抛panic了,若想恢复该panic,我们可以在main函数中定义recover即可
总结
panic和recover都和错误有关,那么我们应该如何定义错误呢,其实这对于我们运维深有感悟,面对程序业务日志,我们再做日志分析的时候,我们不清楚哪些是应该抓出来,要不就是一条不够,要查询上下文,当协程足够多的时候,查询起来会分麻烦,所以,作为运维,希望在设计错误消息的时候,确保每条日志包含的信息足够多,最好不需要借助文件上下文分析的最好。
把panic和recover看了一个大概。哎。

















