6.1.错误

Go语言中使用builtin包下error接口作为错误类型

Go语言中错误都作为方法/函数的返回值

自定义错误类型

//Learn_Go/main.go
package main import (
"errors"
"fmt"
) func demo(i,k int) (r int, e error) {
if k == 0 {
e = errors.New("除数不能为0")
return
}
r = i/k
return
} func main() {
//result,error := demo(6,3)
result,e := demo(6,0)
if e != nil{
fmt.Println("执行错误,错误信息为:",e) //执行错误,错误信息为: 除数不能为0
return
}
fmt.Println("执行成功,结果:",result) //执行成功,结果: 2
}

6.2.defer

Go语言中defer可以完成延迟功能,当前函数执行完成后执行defer功能

defer最常用的就是关闭连接(数据库,文件等),可以打开连接后紧跟defer进行关闭

(1)Go语言中defer无论写到哪里都是最后执行,不用非要把关闭代码写在最后

//Learn_Go/main.go
package main import "fmt" func main() {
fmt.Println("打开连接")
//defer fmt.Println("关闭连接")
defer func() {
fmt.Println("关闭连接") //defer执行
}()
fmt.Println("进行操作")
} //结果
打开连接
进行操作
关闭连接

(2)多个defer

多重defer采用栈结构执行,先产生后执行

在很多代码结构中都可能出现产生多个对象,而程序希望这些对象倒叙关闭,多个defer正好可以解决这个问题

//Learn_Go/main.go
package main import "fmt" func main() {
fmt.Println("打开连接A")
defer fmt.Println("关闭连接A")
fmt.Println("打开连接B")
defer fmt.Println("关闭连接B")
fmt.Println("打开连接C")
defer fmt.Println("关闭连接C")
fmt.Println("进行操作")
} //结果
打开连接A
打开连接B
打开连接C
进行操作
关闭连接C
关闭连接B
关闭连接A

(3)defer和return结合

defer与return同时存在时,要把return理解成两条执行结合,一个指令是给返回值

赋值,另一个指令返回跳出函数

defer和return时整体执行顺序

  • 先给返回值赋值
  • 执行defer
  • 返回跳出函数

(4)没有定义返回值接收变量,执行defer时返回值已经赋值

//Learn_Go/main.go
package main import "fmt" func demo() int {
i := 1
defer func() {
i = i + 2
}()
return i
} func main() {
fmt.Println(demo()) //1
}

(5)声明接收返回值变量,执行defer时修改了返回值内容

//Learn_Go/main.go
package main import "fmt" func demo() (z int) {
i := 1
defer func() {
z = i + 2
}()
return
} func main() {
fmt.Println(demo()) //3
}

6.3.panic

panic是build中函数,当执行到panic后,终止剩余代码执行,并打印错误栈信息。

//Learn_Go/main.go
package main import "fmt" func main() {
fmt.Println("111")
panic("错误信息")
fmt.Println("222")
} //结果
111
panic: 错误信息 goroutine 1 [running]:
main.main()
C:/Users/86158/Desktop/Learn_Go/main.go:8 +0x82

panic不是立即停止程序,defer还是执行的

//Learn_Go/main.go
package main import "fmt" func main() {
defer fmt.Println("执行defer的内容")
fmt.Println("111")
panic("错误信息")
fmt.Println("222")
} //结果
111
执行defer的内容
panic: 错误信息 goroutine 1 [running]:
main.main()
C:/Users/86158/Desktop/Learn_Go/main.go:9 +0xdc

6.4.recover

 recover()表示回复程序的panic(),让程序正常执行

rcover()是和panic一样都是builtin中函数,可以接受panic的信息,恢复程序的正常执行

recover()一般在defer内部,如果没有panic信息,返回nil;如果有panic,recover会把panic状态取消

//Learn_Go/main.go
package main import "fmt" func main() {
defer func() {
if error := recover();error != nil{
fmt.Println("panic为:", error)
}
}()
fmt.Println("111")
panic("出现了错误信息")
fmt.Println("222")
} //结果
111
panic为: 出现了错误信息

函数调用过程中panic和recover()

  • recover()只能恢复当前函数级或当前函数调用函数中的panic(),恢复后调用当前级别函数结束,但是调用此函数的函数可以继续执行
  • panic会一直向上传递,如果没有recover()则表示程序终止,但是碰见了recover(),recover()所在级别函数表示没有panic,panic就不会向上传递
//Learn_Go/main.go
package main import "fmt" func demo1() {
fmt.Println("demo1上半部分")
demo2()
fmt.Println("demo1下半部分")
} func demo2() {
fmt.Println("demo2上半部分")
demo3()
fmt.Println("demo2下半部分")
} func demo3() {
fmt.Println("demo3上半部分")
panic("demo3中出现panic")
fmt.Println("demo3下半部分")
} func main() {
fmt.Println("程序开始")
demo1()
fmt.Println("程序结束")
} //结果
程序开始
demo1上半部分
demo2上半部分
demo3上半部分
panic: demo3中出现panic

 demo3添加recover() 

//Learn_Go/main.go
package main import "fmt" func demo1() {
fmt.Println("demo1上半部分")
demo2()
fmt.Println("demo1下半部分")
} func demo2() {
fmt.Println("demo2上半部分")
demo3()
fmt.Println("demo2下半部分")
} func demo3() {
defer func() {
recover()
}()
fmt.Println("demo3上半部分")
panic("demo3中出现panic")
fmt.Println("demo3下半部分")
} func main() {
fmt.Println("程序开始")
demo1()
fmt.Println("程序结束")
} //结果
程序开始
demo1上半部分
demo2上半部分
demo3上半部分
demo2下半部分
demo1下半部分
程序结束

 demo2添加recover()

//Learn_Go/main.go
package main import "fmt" func demo1() {
fmt.Println("demo1上半部分")
demo2()
fmt.Println("demo1下半部分")
} func demo2() {
defer func() {
recover()
}()
fmt.Println("demo2上半部分")
demo3()
fmt.Println("demo2下半部分")
} func demo3() {
fmt.Println("demo3上半部分")
panic("demo3中出现panic")
fmt.Println("demo3下半部分")
} func main() {
fmt.Println("程序开始")
demo1()
fmt.Println("程序结束")
} //结果
程序开始
demo1上半部分
demo2上半部分
demo3上半部分
demo1下半部分
程序结束

  

6.Go-错误,defer,panic和recover的更多相关文章

  1. GOLANG错误处理最佳方案errors wrap, Defer, Panic, and Recover

    Simple error handling primitives:        https://github.com/pkg/errors Defer, Panic, and Recover:    ...

  2. 15 Defer, Panic, and Recover

    Defer, Panic, and Recover 4 August 2010 Go has the usual mechanisms for control flow: if, for, switc ...

  3. Golang 入门系列(十四)defer, panic和recover用法

    以前讲过golang 的基本语法.但是,只是讲了一些基础的语法,感兴趣的可以看看以前的文章,https://www.cnblogs.com/zhangweizhong/category/1275863 ...

  4. go语言defer panic recover用法总结

    defer defer是go提供的一种资源处理的方式.defer的用法遵循3个原则 在defer表达式被运算的同时,defer函数的参数也会被运算.如下defer的表达式println运算的同时,其入 ...

  5. panic和recover的使用规则

    转自个人博客 chinazt.cc 在上一节中,我们介绍了defer的使用. 这一节中,我们温习一下panic和recover的使用规则. 在golang当中不存在tye ... catch 异常处理 ...

  6. Golang错误处理函数defer、panic、recover、errors.New介绍

    在默认情况下,当发生错误(panic)后,程序就会终止运行 如果发生错误后,可以捕获错误,并通知管理人员(邮件或者短信),程序还可以继续运行,这当然无可厚非 errors.New("错误信息 ...

  7. Go语言异常处理defer\panic\recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  8. 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)

    这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...

  9. go语言中使用defer、panic、recover处理异常

    go语言中的异常处理,没有try...catch等,而是使用defer.panic.recover来处理异常. 1.首先,panic 是用来表示非常严重的不可恢复的错误的.在Go语言中这是一个内置函数 ...

随机推荐

  1. 数据仓库003 - 复习Linux shell命令 - 用户用户组 sudo 权限 du-sh find 

    一.用户用户组 [root@localhost ~]# ll /usr/sbin/user* -rwxr-x--- root root -- /usr/sbin/useradd -rwxr-x--- ...

  2. Oracle 存储过程包(Package、Package Body)

    初出茅庐,不知原来存储过程还可以写得如此复杂,而且还竟然可以调试! 好吧,得整理一下存储过程的一些语法,以备以后用到时可以查阅. 使用数据库:Oracle 数据库工具:PL/SQL Developer ...

  3. python接口自动化4-常用取token值方法

    前言 在接口测试中我们经常是需要一个登陆token,或者获取其他用到的参数来关联下一个接口用到的参数.这里介绍一些本人常用的方法. 一.简介 不过在哪里我们也是能实现自动化api测试的,我们都知道to ...

  4. 汇总Anaconda与ROS冲突解决方法

    汇总一下在网上找到的Anaconda与ROS冲突解决方法,如果还有其他人找到其他方法,欢迎留言. anaconda和ros的安装就不介绍了. 1. 在某视频网站上一个印度小哥提出的方法 安装完成后,在 ...

  5. Django学习笔记(11)——开发图书管理页面

    一,项目题目: 开发图书管理页面 该项目主要练习Django对多个数据库进行增删改查的操作. 二,项目需求: 基础需求:75% 1. 列出图书列表.出版社列表.作者列表 2. 点击作者,会列出其出版的 ...

  6. laravel 广播细节讲解

    1.应用场景 1.通知(Notification) 或 信号(Signal) 2.通知是最简单的示例,也最经常用到.信号也可看作是通知的一种展现形式,只不过信号没有UI而已. 3.Activity S ...

  7. 2019-11-25-如何在国内发布-UWP-应用

    原文:2019-11-25-如何在国内发布-UWP-应用 title author date CreateTime categories 如何在国内发布 UWP 应用 lindexi 2019-11- ...

  8. WPF ItemsSource Order by Getter

    public ObservableCollection<CustomerModel> CustomerCollection { get { if(customerCollection!=n ...

  9. App_Code下类无法引用问题

    App_Code 下创建的.cs文件仅仅是“内容”不是代码.设置文件为“编译”就可正常引用.

  10. Spring Boot @EnableAutoConfiguration解析

    刚做后端开发的时候,最早接触的是基础的spring,为了引用二方包提供bean,还需要在xml中增加对应的包<context:component-scan base-package=" ...