🌈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 mainimport ("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!") // 触发 panicfmt.Println("This line will not be executed.")
}
//输出
//Starting the program...
//Recovered from: A critical error occurred!
defer
在 Go 语言中,defer 关键字用于确保在函数执行结束时执行某些操作,无论函数是正常返回还是因为发生错误而提前退出。defer 的主要用途包括资源清理(如关闭文件、解锁互斥锁等)和执行一些必要的收尾工作。
package mainimport ("fmt""os"
)func main() {//创建文件f := createFile("/tmp/defer.txt")//使用 defer 关键字,确保在 main 函数结束时调用 closeFile(f)。//这意味着在 main 函数退出时,文件 f 将被关闭,无论是正常退出还是因为 panicdefer 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 mainimport "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 mainimport "fmt"func main() {x := 10defer fmt.Println(x) // x 的值为 10x = 20
}//输出10
defer用途
- 资源清理:如关闭文件、网络连接等。
- 解锁互斥锁:在并发编程中,确保在使用完共享资源后释放锁。
- 记录日志:在函数返回时记录执行情况。
💪无人扶我青云志,我自踏雪至山巅。