Go异常处理errors

简单用法

代码实现
// Errors
package main

import (
	"errors"
	"fmt"
	"log"
)

var errDivByZero = errors.New("division by zero") //定义全局的错误变量

func div(x, y int) (int, error) {
	if 0 == y {
		return 0, errDivByZero
	}

	return x / y, nil
}

func main() {
	z, err := div(5, 0)
	if err == errDivByZero {
		log.Fatalln(err)
	}

	fmt.Println(z)
}

执行结果
# go run Errors.go
2018/02/27 11:39:30 division by zero
exit status 1
  • 使用log.Fatalln(err)可导致程序返回状态为1,使用fmt输出则不会

自定义错误类型

代码实现
// CustomError
package main

import (
	"fmt"
	"log"
)

//自定义一个错误类型,也叫接口
type DivError struct {
	x, y int
}

//实现errors.Error()接口方法
func (DivError) Error() string {
	return "division by zero"
}

func div(x, y int) (int, error) {
	if y == 0 {
		return 0, DivError{x, y} //返回自定义错误类型,因为DivError实现了errors接口,所以可以直接返回
	}

	return x / y, nil
}

func main() {
	z, err := div(5, 0)
	if err != nil {
		switch e := err.(type) {
		case DivError:
			fmt.Println(e, e.x, e.y)
		default:
			fmt.Println(e)
		}

		log.Fatal(err)
	}

	fmt.Println(z)
}

执行结果
# go run CustomError.go
division by zero 5 0
2018/02/27 14:05:48 division by zero
exit status 1

异常捕捉

简单的异常触发和捕捉

  • 内置函数panic发起一个异常,立即中断当前函数流程,执行延迟调用
  • 内置函数recover可捕获并返回panic提交的错误对象
代码实现
// Panic1
package main

import (
	"fmt"
	"log"
)

func main() {
	defer func() {
		if err := recover(); err != nil { //补捉错误
			log.Fatal(err)
		}
	}()

	panic("i am dead") //触发异常

	fmt.Println("exit.") //永远不会执行
}

执行结果
# go run Panic1.go
2018/02/27 14:19:31 i am dead
exit status 1

错误中断沿调用栈向外传递

中断性错误沿调用栈传递,要么被外层捕捉,要么导致进程崩溃

代码实现
// Panic2
package main

import (
	"fmt"
	"log"
)

//函数内没有捕获异常,中断会继续向上抛
func test() {
	defer fmt.Println("test1: i have not catch error")
	defer fmt.Println("test2: i have not catch error")

	panic("i am dead")
}

func main() {
	defer func() {
		log.Fatal(recover()) //异常中断在此处被捕获
	}()

	test()
}
执行结果
# go run Panic2.go
test2: i have not catch error
test1: i have not catch error
2018/02/27 14:34:46 i am dead
exit status 1

连续调用panic,仅最后一个会被recover捕获

代码实现
// Panic3
package main

import (
	"log"
)

func main() {
	defer func() {
		for {
			if err := recover(); err != nil { //只能捕获到最后一次异常
				log.Println(err)
			} else {
				log.Fatalln("fatal")
			}
		}
	}()

	defer func() {
		panic("yes, you are dead") //再次抛出异常
	}()

	panic("i am dead") //首次抛出异常
}

执行结果
# go run Panic3.go
2018/02/27 14:51:31 yes, you are dead
2018/02/27 14:51:31 fatal
exit status 1

转载于:https://my.oschina.net/renhc/blog/1624970

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值