Golang学习笔记(6)资源管理和错误处理

本文深入探讨了Go语言中的资源管理和错误处理机制,包括defer调用的使用场景,如文件的打开与关闭,锁的加锁与解锁,以及打印头尾等。详细解析了错误处理的两种方式,通过示例展示了如何实现统一的错误处理逻辑,并介绍了panic和recover的使用方法及区别。同时,文章还提供了错误处理的综合实例,结合defer、panic和recover的实际应用。

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

第六章 资源管理和错误处理


defer调用
  • 确保调用在函数结束时发生
  • 参数在defer语句时计算
  • defer列表为先进后出
func writeFile(filename string) {
	file, err := os.Create(filename)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	writer := bufio.newWrite(file)
	defer writer.Flush()

	f := fib.Fibonacci()
	for i := 0; i < 20; i++ {
		fmt.Fprintln(writer, f())
	}
}

func main() {
	writeFile("fib.txt")
}
何时使用defer调用
  • Open / Close
  • Lock / Unlock
  • PrintHeader / PrintFooter
错误处理
file, err := os.Open("abc.txt")
if err != nil {
	if pathError, ok := err.(*os.PathError); ok {
		fmt.Println(pathError.Err)
	} else {
		fmt.Println("unknown error", err)
	}

}
错误处理二
  • 如何实现统一的错误处理逻辑
type appHandler func(writer http.ResponseWriter,
	request *http.Request) error

func errWrapper(
	handler appHandler) func(
	http.ResponseWriter, *http.Request) {
	return func(writer http.ResponseWriter,
		request *http.Request) {

		err := handler(writer, request)

		if err != nil {
			log.Printf("Error occurred "+
				"handling request: %s",
				err.Error())

			// system error
			code := http.StatusOK
			switch {
			case os.IsNotExist(err):
				code = http.StatusNotFound
			case os.IsPermission(err):
				code = http.StatusForbidden
			default:
				code = http.StatusInternalServerError
			}
			http.Error(writer,
				http.StatusText(code), code)
		}
	}
}

func main() {
	http.HandleFunc("/",
		errWrapper(filelisting.HandleFileList))

	err := http.ListenAndServe(":8888", nil)
	if err != nil {
		panic(err)
	}
}

panic
  • 停止当前函数执行
  • 一直向上返回,执行每一层的defer
  • 如果没有遇见recover,程序退出
recover
  • 仅在defer调用中使用
  • 获取panic的值
  • 如果无法处理,可以重新panic
func tryRecover() {
	defer func() {
		r := recover()
		if r == nil {
			fmt.Println("Nothing to recover. " +
				"Please try uncomment errors " +
				"below.")
			return
		}
		if err, ok := r.(error); ok {
			fmt.Println("Error occurred:", err)
		} else {
			panic(fmt.Sprintf(
				"I don't know what to do: %v", r))
		}
	}()

	// Uncomment each block to see different panic
	// scenarios.
	// Normal error
	panic(errors.New("this is an error"))		// Output : Error occurred: this is an error

	// Division by zero
	b := 0
	a := 5 / b
	fmt.Println(a)								// Output : Error occurred: runtime error: 
												//			integer divide by zero

	// Causes re-panic
	panic(123)									// Output :
												// 			panic: 123 [recovered]
												// 			panic: I don't know what to do: 123
}

func main() {
	tryRecover()
}

error vs panic
  • 意料之中的 : 使用error. 如 : 文件打不开
  • 意料之外的: 使用panic. 如 : 数组越界
错误处理综合实例
  • defer + panic + recover
  • Type Assertion
  • 函数式编程的应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值