zoukankan      html  css  js  c++  java
  • defer,panic,recover

    Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱。因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个异常。在Go语言中,使用多值返回来返回错误。不要用异常代替错误,更不要用来控制流程。在极个别的情况下,也就是说,遇到真正的异常的情况下(比如除数为0了)。才使用Go中引入的Exception处理:defer, panic, recover。流程可以简要描述为:在代码片段中抛出一个panic的异常,然后在defer中通过recover捕获这个异常,然后正常处理

    一.使用多返回值来处理错误

    import (
    	"errors"
    	"fmt"
    )
    
    func Handle(i int) (int, error) {
    	if i == 0 {
    		return i, errors.New("除数为0")
    	}
    	return 100 / i, nil
    }
    
    func main() {
    	if divint, err := Handle(0); err != nil {
    		fmt.Println(err)
    	} else {
    		fmt.Println(divint)
    	}
    }
    

      

    二.defer

    defer就是用来添加函数结束时执行的语句.因为这个特性,可以将其用作关闭文件句柄等.

    func Handle(i int) (res int) {
    	res = i
    	defer func() {
    		res++
    	}()
    	return res
    }
    
    func main() {
    	i := Handle(0)
    	fmt.Println(i)
    }
    

      

    打印出1, 因为defer中添加了一个函数,在函数返回前改变了命名返回值的值.如果defer语句没有执行,那么defer函数不会添加.

    func Handle(i int) (res int) {
    	res = i
    	return res // 直接返回了,defer没有执行
    	defer func() {
    		res++
    	}()
    	return res
    }
    
    func main() {
    	i := Handle(0)
    	fmt.Println(i)
    }
    

      

    二.panic


    panic 是用来表示非常严重的不可恢复的错误的.可以理解为一般语言的 throw new Exception().调用panic看看,程序立马挂掉,然后Go运行时会打印出调用栈.
    关键的一点是,即使函数执行的时候panic了,函数不往下走了,运行时并不是立刻向上传递panic,而是到defer那,等defer的东西都跑完了,panic再向上传递。所以这时候 defer 有点类似 try-catch-finally 中的 finally。

    三.recover


    捕获panic,被捕获到的panic就不会向上传递了.不过要注意,recover之后,逻辑并不会恢复到panic那个点去,函数还是会在defer之后返回.

    用Go实现类似 try catch 的异常处理:

    import (
    	"fmt"
    )
    
    func Handle(i int) (res int) {
    	if i == 0 {
    		panic("被除数为0")
    	}
    	res = i / 2
    	return res
    }
    
    func main() {
    	defer func() {
    		if err := recover(); err != nil {
    			fmt.Println(err)
    		}
    	}()
    	Handle(0)
    }
    

      

  • 相关阅读:
    【MyBatis】STDOUT_LOGGING和log4j日志
    【MyBatis】resultType与类的字段不同解决办法
    【MyBatis】SqlSession相关的生命周期及作用域
    【MyBatis】XML配置的官网说明
    【Junit】程序员都应会的白盒测试
    【MyBatis】增删改查语句入门
    【MyBatis】我的mybatis第一个程序
    【网络】HTTP知识点(1)
    InitializeComponent报错(提示不存在)
    leetcode 860柠檬水找零问题
  • 原文地址:https://www.cnblogs.com/itfenqing/p/7635107.html
Copyright © 2011-2022 走看看