GO语言基础4 Errors 报错

更多个人笔记见:
github个人笔记仓库
gitee 个人笔记仓库

个人学习,学习过程中还会不断补充~ (后续会更新在github上)

文章目录

自己创建错误

error 信息可以自己定义

GO 复制代码
func main() {
	arg := 2
    arg2 := 4
	err := makeTea(arg)
	if err != nil {
		fmt.Println(err)
	}
	err2 := makeTea(arg2)
	if err2!= nil {
		fmt.Println(err2)
	}
}

//两种创建错误的方式
func makeTea(arg int) error {
	if arg == 2 {
		return fmt.Errorf("no more tea available")
	} else if arg == 4 {
		return errors.New("no more power available")
	}
	return nil
}

panic和recover

基础示范

panic 会报错然后程序返回,recover 结合defer 放在最后匿名函数中执行用于接受 panic

Go 复制代码
package main

import (
	"fmt"
)

func mayPanic() {
	panic("a problem") //手动 panic
}
func main() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println("成功接收Recovered. Error:\n", r)
		}
	}()
	mayPanic()
	fmt.Println("After mayPanic()") // won't output
}
//output:
//成功接收Recovered. Error:
//a problem
panic的返回

通过嵌套函数理解返回方式

Go 复制代码
func a(){
	defer fmt.Println("defer a")
	b()
	fmt.Println("after a")
}
func b(){
	defer fmt.Println("defer b")
	c()
	fmt.Println("after b")
}
func c(){
	defer fmt.Println("defer c")
	panic("this is a panic")
	fmt.Println("after c")
}

func main() {
	a()
}
// defer c
// defer b
// defer a
// panic: this is a panic

修改b部分:可以保证回到a

GO 复制代码
func b() {
	defer func() { //变为立即执行的函数
		fmt.Println("defer b")
		if x := recover(); x != nil {
			fmt.Println("run time panic: %v \n", x)
		}
	}()
	c()
	fmt.Println("after b")
}
//defer c
// defer b
// run time panic: %v 
//  this is a panic
// after a
// defer a

能回到 A 就会先打印出 after a 然后再结束就打印出 defer a

用于保证g()函数执行的中间件
GO 复制代码
func protect(g func()) {
	defer func(){
		log.Println("done")
		if x:=recover();x!=nil{
			log.Printf("run time panic:%v",x)
		}
	}()
	log.Println("start")
	g()   //执行g   如果有问题会返回上去的
}
panic和recover的嵌套顺序
打印最先 panic

如果在defer调用的函数中也有panic,会打印最早的panic (没有recover的时候

GO 复制代码
func main() {
	a()
}

func a() {
	defer b()
	panic("a panic")
}

func b() {
	defer fb()
	panic("b panic")
}

func fb() {
	panic("fb panic")
}
// panic: a panic
// panic: b panic
// panic: fb panic

这个例子中,先 panic a 然后调用 b,继续向下迭代

recover 捕获最近 panic
GO 复制代码
func main() {
	defer catch("main")  //增加捕获
	a()
}

func catch(name string) {
	if r := recover(); r != nil {
		fmt.Println(name, "recover:", r)
		//println会打印地址
	}
}

func a() {
	defer b()
	panic("a panic")
}

func b() {
	defer fb()
	panic("b panic")
}

func fb() {
	defer catch("fb")    // //增加捕获
	panic("fb panic")
}

// fb recover: fb panic
// main recover: b panic

执行顺序: a 中 panic ->defer 调用 b ->b 中 panic->调用 fb->fb

中 panic->defer 调用 catch,抓住的是 fb panic ->回到 main 中 defer->抓住的是b panic (因为 fb 的 panic 已经被捕获,会向前推)

相关推荐
南囝coding2 分钟前
最近Vibe Coding的经验总结
前端·后端·程序员
CHEN5_027 分钟前
【Java面试题】缓存穿透
java·开发语言·数据库·redis·缓存
丘山子16 分钟前
Python 布尔运算的优雅实践
后端·python·面试
汪子熙29 分钟前
理解 SSH Agent 的工作原理与应用场景
后端
UQWRJ30 分钟前
R语言基础图像及部分调用函数
开发语言·r语言
苏琢玉39 分钟前
如何优雅地处理多种电商优惠规则?我用 PHP 封装了一个 Promotion Engine
后端·php·composer
豌豆花下猫41 分钟前
Python 潮流周刊#113:用虚拟线程取代 async/await
后端·python·ai
武子康43 分钟前
大数据-58 Kafka 消息发送全流程详解:序列化、分区策略与自定义实现
大数据·后端·kafka
福大大架构师每日一题43 分钟前
2025-08-02:最多 K 个元素的子数组的最值之和。用go语言,给定一个整数数组 nums 和一个正整数 k,请找出所有长度最多为 k 的连续子数组,计算
后端
Debug笔记43 分钟前
你真的理解 Java 中的线程池吗?一次“查不出原因的接口变慢”的真实排查经历
后端