当前位置: 首页 > article >正文

【go从零单排】panic、recover、defer

挪威特罗姆瑟夜景

🌈Don’t worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。

📗概念

在 Go 语言中,panic 是一种用于处理异常情况的机制。它允许程序在遇到严重错误时停止执行,并可以在调用栈中向上抛出错误,直到被捕获或程序崩溃。

💻代码

panic

package main

//导入os包
import "os"

func main() {
	//这行代码立即引发一个panic,并打印出信息 "a problem"。程序会在这一行停止执行,不会继续执行后面的代码。
	panic("a problem")
	//后面的代码都不会执行
	_, err := os.Create("/tmp/file")
	if err != nil {
		panic(err)
	}
}

//输出
//panic: a problem
//goroutine 1 [running]:
//main.main()
//        /Users/dudusman/GolandProjects/awesomeProject/post.go:8 +0x25
//exit status 2

recover

使用 recover 函数来捕获 panic,从而防止程序崩溃。
recover 只能在 defer 的函数中有效。

package main

import (
    "fmt"
)

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from:", r)
        }
    }()

    fmt.Println("Starting the program...")
    panic("A critical error occurred!") // 触发 panic
    fmt.Println("This line will not be executed.")
}
//输出
//Starting the program...
//Recovered from: A critical error occurred!

defer

在 Go 语言中,defer 关键字用于确保在函数执行结束时执行某些操作,无论函数是正常返回还是因为发生错误而提前退出。defer 的主要用途包括资源清理(如关闭文件、解锁互斥锁等)和执行一些必要的收尾工作。

package main

import (
	"fmt"
	"os"
)

func main() {
	//创建文件
	f := createFile("/tmp/defer.txt")
	//使用 defer 关键字,确保在 main 函数结束时调用 closeFile(f)。
	//这意味着在 main 函数退出时,文件 f 将被关闭,无论是正常退出还是因为 panic
	defer closeFile(f)
	//调用 writeFile 函数,传入文件指针 f,在文件中写入数据
	writeFile(f)
}

// createFile 函数接受一个字符串参数 p(文件路径),尝试创建该文件。
func createFile(p string) *os.File {
	fmt.Println("creating")
	f, err := os.Create(p)
	if err != nil {
		panic(err)
	}
	//如果成功,返回文件指针 f。
	return f
}

func writeFile(f *os.File) {
	fmt.Println("writing")
	fmt.Fprintln(f, "data")

}

// closeFile 函数接受一个文件指针 f,尝试关闭文件。
func closeFile(f *os.File) {
	fmt.Println("closing")
	err := f.Close()
	//关闭文件时发生错误,打印错误信息到标准错误输出,并使用 os.Exit(1) 退出程序
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}

  • defer 语句会将其后面指定的函数调用推迟到包含它的函数返回时执行

多个defer

package main

import "fmt"

func main() {
	defer fmt.Println("first")
	defer fmt.Println("second")
	defer fmt.Println("third")
}
//输出
//third
//second
//first

🔍理解

  • panic 通常用于表示程序运行时的不可恢复错误,例如数组越界、空指针解引用等。
  • 当调用 panic 时,程序会停止当前的执行流程,并开始逐层返回到调用栈中的上层函数。
  • 多个 defer 语句会按照后进先出(LIFO)的顺序执行。这意味着最后一个被推迟的函数会最先执行。

💡 Tips小知识点

  • defer 语句的参数在声明时就会被求值,而不是在执行时。这意味着如果在 defer 语句中使用变量,其值将在 defer 被调用时确定,而不是在函数返回时。
package main

import "fmt"

func main() {
	x := 10
	defer fmt.Println(x) // x 的值为 10
	x = 20
}

//输出10

defer用途

  • 资源清理:如关闭文件、网络连接等。
  • 解锁互斥锁:在并发编程中,确保在使用完共享资源后释放锁。
  • 记录日志:在函数返回时记录执行情况。

💪无人扶我青云志,我自踏雪至山巅。
在这里插入图片描述


http://www.kler.cn/a/392037.html

相关文章:

  • 45.第二阶段x86游戏实战2-hook监控实时抓取游戏lua
  • const限定符-C语言中指针的“可变与不可变”法则
  • Apache ECharts
  • scala的练习题
  • Linux下MySQL的简单使用
  • 从0开始学PHP面向对象内容之(常用魔术方法续一)
  • 51c自动驾驶~合集10
  • python 京东api怎么写
  • 深入理解Java构造方法和接口:如何调用父类构造方法,接口能否包含方法实现?
  • MySQL缓存使用率超过80%的解决方法
  • 6.10 Queue接口/Deque接口 模拟栈与队列分析
  • 为什么谷歌SEO需要周期性维护?
  • 【excel】easy excel如何导出动态列
  • 离线安装GDAL与MapServer:在银河麒麟V10上的快速指南
  • [基础] 001 move的介绍
  • 机器学习:随机森林——基于决策树的模型
  • (蓝桥杯C/C++)——搜索
  • 036 RabbitMQ消息确认 死信队列 延时队列
  • 脑机接口、嵌入式 AI 、工业级 MR、空间视频和下一代 XR 浏览器丨RTE2024 空间计算和新硬件专场回顾
  • 接口测试框架+数据驱动
  • Fish Agent V0.13B:Fish Audio的语音处理新突破,AI语音助手的未来已来!
  • 集合类源码浅析のJDK1.8ConcurrentHashMap(上篇)
  • Go语言的并发安全与互斥锁
  • 使用cloudflare搭建私人docker镜像站
  • 【深圳大学/大学物理实验2】弗兰克-赫兹实验预习题参考
  • PL/SQL执行.sql文件