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下半部分
程序结束

  

最新文章

  1. Codeforces 划水
  2. canvas对象arc函数的使用-遁地龙卷风
  3. 第十八篇:在SOUI中实现PreTranslateMessage
  4. Nice Sequence_线段树***
  5. asp.net的JSON数据进行序列化和反序列化
  6. JavaScript正则表达式(二)
  7. Struts2应用的开发步骤
  8. wordpress在Linux nginx下权限设置
  9. 【leetcode】com/problems/surrounded-regions/
  10. java解析xml文件四种方式
  11. Constructing Roads(1102 最小生成树 prim)
  12. 转: Transact-sql游标使用详解~~很详细
  13. struts2+hibernate+spring配置版框架搭建以及简单测试(方便脑补)
  14. 《软工实践》第零次作业 - 一些QA
  15. poj3268 Silver Cow Party(两次dijkstra)
  16. OLAP了解与OLAP引擎——Mondrian入门
  17. Zookeeper基本数据模型
  18. Spark SQL Hive Support Demo
  19. STL - 容器 - Map(二)
  20. IT常用设备及服务器安全公告或漏洞地址pa安全预警微软安全公告 HP 安全公告AIX 安全公告REDHAT安全公告ORACLE 安全公告F5 安全公告 Cisco 安全公告Juniper 安全公告 VMware 安全公告IOS 安全公告

热门文章

  1. 多台Linux 7.x服务器具有相同的UUID网络链接参数,肿么办?
  2. JDBC数据库连接测试工具
  3. Vue.js 源码分析(二十四) 高级应用 自定义指令详解
  4. C# 实现 奇数偶数排序,奇数在前,偶数在后
  5. ASP.NET list<object> OBJECT.clean()会清空session['OBJECT']的值的问题
  6. 如何使用Charles让手机访问PC自定义域名?
  7. mp4文件格式解析二
  8. docker操作命令大全和后台参数
  9. 那些年我们走过的坑,对Fortify的漏洞进行总结
  10. Android 自定义水平进度条的圆角进度