昨天我们留了个尾巴今天就解决掉。我们先从defer说起--下面先看一个实例
代码语言:javascript复制func main() {
a := a(1)
defer fmt.Println(a)
b := b(2)
defer fmt.Println(b)
result := a b
defer fmt.Println(result)
}
func a(a int) string {
return strconv.Itoa(a)
}
func b(b int) string {
return strconv.Itoa(b)
}
这是一个很简的实例在说之前我们先看看结果
先打印的顺序跟defer出现的顺序相反,这是为啥呢?其实defer是一个延缓处理的过程,采用压栈和出栈来完成整个流程。内部流程大致如下图
好了,根据上面我们了解的defer的接下来我们说说异常Panic。
我们在开发过程中经常会遇到程序莫名的闪退和终止,其实这些大部分是由于异常导致的----服务端数据没按照正常约定格式,文件缺失,数据库驱动程序不对号,文件路径错误等等
下面我们先看一个经常使用的粒子:字符串转换数字
代码语言:javascript复制func strToNum(str string) (int, error) {
return strconv.Atoi(str)
}
上面是一个很常规的函数。我们给一些测试用例来看看:
代码语言:javascript复制 des, err := strToNum("123.3")
fmt.Println(des,err)
des, err = strToNum("23asd")
fmt.Println(des,err)
des, err = strToNum("234")
fmt.Println(des,err)
有了用例我们来看看结果
可以看出系统给出了错误,但是生成中我们不可能去认为的观察这些,那么对于十分严重的会导致后续的一系列雪崩的errror就不能简单的忽略啦。那么就要认为的去抛出异常--使用panic抛出异常
代码语言:javascript复制des, err := strToNum("123.3")
fmt.Println(des, err)
if err != nil {
panic(err)
}
des, err = strToNum("23asd")
fmt.Println(des, err)
des, err = strToNum("234")
fmt.Println(des, err)
上例中我们看到了一个异常产生的粒子,那么对于异常我们怎么来抓取处理呢,我们能否给予这些异常一些任性话的意义,甚至对异常进行修改呢?答案是可以的
代码语言:javascript复制func strToNum(str string) (int, error) {
var err error
var dest int
defer func() {
switch p:=recover();p {
case nil:
case p:
err = fmt.Errorf("数据转换异常: %v", p)
fmt.Println(err)
default:
panic(p)
}
}()
dest , err = strconv.Atoi(str)
if err!=nil {
panic(err)
}
return dest,err
}
结合上栗我们看到使用recover来捕获系统抛出的异常或者是人为抛出的致命性性异常提示,我们来看看结果
通过今天的学习我们首先完成了defer的认知以及defer打压栈出栈过程,然后接触了异常panic以及异常的应对策略recover。明天我们就要接触go中比较复杂的数据类型struct,这个是一个比较综合的数据类型,希望大家吧今天以及之前的基础好好的巩固一下……