Golang入门笔记(14)—— 错误处理

本文介绍Go语言中的异常处理机制,包括如何使用defer...recover来捕获并处理panic异常,以及如何通过errors.New自定义错误。文章还展示了如何结合panic停止程序执行流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        来一个除以0的异常,代码如下:

package main

import "fmt"

func main() {

	fmt.Println("before")
	divNum()
	fmt.Println("after")
}

func divNum() {
	num1 := 10
	num2 := 0
	result := num1 / num2
	fmt.Println(result)
}

        console 异常:

before
panic: runtime error: integer divide by zero

goroutine 1 [running]:
main.divNum()
        C:/Users/Lenovo/IdeaProjects/go-helloworld/class02/demo06/main.go:15 +0x11
main.main()
        C:/Users/Lenovo/IdeaProjects/go-helloworld/class02/demo06/main.go:8 +0x5b
exit status 2

        恐慌: 运行时 整数除以零的恐慌。

        before 输出后,遇到恐慌异常,代码运行时,因为错误恐慌中断,后面的代码 after并没有执行出来。常常我们不想程序的代码流就这么在运行时就中断掉,就需要引入一些技术,错误能被捕获并处理掉。

        在java中有try...catch...finally 来处理异常,在Go中,为了追求代码的优雅,采用的是defer...recover来处理这里的恐慌panic 。

defer recover 机制处理错误:

              defer 前面学过了,但是什么是recover函数?

        官方解释及有道翻译:

        The recover built-in function allows a program to manage behavior of a panicking goroutine. 内置包的recover函数允许程序管理恐慌goroutine go程序 的行为。
        Executing a call to recover inside a deferred function (but not any function called by it) stops the panicking sequence by restoring normal execution and retrieves the error value passed to the call of panic. 在延迟函数(而不是它调用的任何函数)内部执行恢复调用,通过恢复正常执行来停止恐慌序列,并检索传递给panic调用的错误值。
        If recover is called outside the deferred function it will not stop a panicking sequence.如果在deferred函数外部调用recover,则不会停止恐慌序列。
        In this case, or when the goroutine is not panicking, or if the argument supplied to panic was nil, recover returns nil. Thus the return value from recover reports whether the goroutine is panicking.在这种情况下,或者当goroutine没有panic,或者提供给panic的参数为nil时,recover将返回nil。因此,recover的返回值报告goroutine是否出现异常。

这里,nil是零值,返回nil 则说明 goroutine 有错误。 代码如下:
package main

import "fmt"

func main() {

	fmt.Println("before")
	divNum()
	fmt.Println("after")
}

func divNum() {

	//利用defer + recover 捕获错误

	// 1.defer 后加一个匿名函数调用。
	defer func() {
		// 2.匿名函数内开一个局部变量,看 recover返回是 nil 还是错误。。
		err := recover() 
		//3.如果recover 返回的不是零,说明goroutine有错误,打印该错误。
		if err != nil {
			fmt.Println(err)
		}
	}()

	num1 := 10
	num2 := 0
	result := num1 / num2
	fmt.Println(result)
}
查看 console 输出:
before
runtime error: integer divide by zero
after
Go语言的自定义错误:
        由于 runtime error: integer divide by zero 对我们不是很友好,看下Go语言是如何支持自定义错误的。
       自定义错误,需要调用errors包瞎的New函数进行操作,函数会返回一个error类型。
package main

import (
	"errors"
	"fmt"
)

func main() {

	fmt.Println("before")
	err := divNum()
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println("after")
}

func divNum() (err error) {

	num1 := 10
	num2 := 0

	// 抛出自定义错误。
	if num2 == 0 {
		err := errors.New("除数不能为0")
		return err
	} else {
		result := num1 / num2
		fmt.Println(result)
		return nil
	}

}
上面发生错误,程序正常执行了,有时候,我们希望发生错误,程序停止执行。

        panic(err) //抛出异常,停止代码流。相当于java 中的new Exception();

package main

import (
	"errors"
	"fmt"
)

func main() {

	fmt.Println("before")
	err := divNum()
	if err != nil {
		fmt.Println(err)
		panic(err) //抛出异常,停止代码流。相当于java 中的new Exception();
	}
	fmt.Println("after")
}

func divNum() (err error) {

	num1 := 10
	num2 := 0

	// 抛出自定义错误。
	if num2 == 0 {
		err := errors.New("除数不能为0")
		return err
	} else {
		result := num1 / num2
		fmt.Println(result)
		return nil
	}

}
        That's all , next point ...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值