分享
  1. 首页
  2. 文章

goLang异常处理

一个简单搬运工 · · 6749 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

defer

defer是go提供的一种资源处理的方式。defer的用法遵循3个原则在defer表达式被运算的同时,defer函数的参数也会被运算。如下defer的表达式println运算的同时,其入参i也会被运算,结果为初始化值0,故defer调用中会打印"0"

func a() {
i := 0
defer fmt.Println(i)
i++
return

defer函数在一个函数return之后遵循后进先出的调用原则,如下打印结果为3210

func b() {
 for i := 0; i < 4; i++ {
 defer fmt.Print(i)
 }
}

defer函数可能会读取并赋值给所在函数的返回值,如下返回值为2

func c() (i int) {
defer func() { i++ }()
return 1
}

针对上述的第三点有如下三种情况:

例1:<br>func f() (result int) {
 defer func() {
 result++
 }()
 return 0
}
 
例2:<br>func f() (r int) {
 t := 5
 defer func() {
 t = t + 5
 }()
 return t
}
 
例3:<br>func f() (r int) {
 defer func(r int) {
 r = r + 5
 }(r)
 return 1
}

函数返回的过程是这样的:先给返回值赋值,然后再调用defer表达式,最后才是返回到调用函数中
先看例1,它可以改写成这样:

func f() (result int) {
 result = 0 //return语句不是一条原子调用,return xxx其实是赋值+ret指令
 func() { //defer被插入到return之前执行,也就是赋返回值和ret指令之间
 result++
 }()
 return
}

所以这个返回值是1。

再看例2,它可以改写成这样:

func f() (r int) {
 t := 5
 r = t //赋值指令
 func() { //defer被插入到赋值与返回之间执行,这个例子中返回值r没被修改过
 t = t + 5
 }
 return //空的return指令
}

所以这个的结果是5。

最后看例3,它改写后变成:

func f() (r int) {
 r = 1 //给返回值赋值
 func(r int) { //这里改的r是传值传进去的r,不会改变要返回的那个r值
 r = r + 5
 }(r)
 return //空的return
}

所以这个例子的结果是1。

panic和recover

panic和recover的使用需要遵循以下原则:

defer 需要放在 panic 之前定义,另外recover只有在 defer 调用的函数中才有效。
recover处理异常后,逻辑并不会恢复到 panic 那个点去,函数跑到 defer 之后的那个点.
多个 defer 会形成 defer 栈,后定义的 defer 语句会被最先调用

使用recover捕获程序中的错误的用法如下

package main
 
import (
 "fmt"
 "time"
)
 
func main() {
 f()
 fmt.Println("end")
}
 
func f() {
 defer func() {   //必须要先声明defer,否则不能捕获到panic异常
  fmt.Println("defer start")
  if err := recover(); err != nil {
   fmt.Println(err) //这里的err其实就是panic传入的内容,"bug"
  }
  fmt.Println("defer end")
 }()
 for {
  fmt.Println("func begin")
  a := []string{"a", "b"}
  fmt.Println(a[3])  // 越界访问,肯定出现异常
  panic("bug")   // 上面已经出现异常了,所以肯定走不到这里了。
  fmt.Println("func end") // 不会运行的.
  time.Sleep(1 * time.Second)
 }
}

输出结果如下

1 func begin
2 defer start
3 runtime error: index out of range
4 defer end
5 end


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:一个简单搬运工

查看原文:goLang异常处理

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
6749 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏