自定义错误类型

This commit is contained in:
yangyudong 2025-04-10 19:32:32 +08:00
parent 3c981f9315
commit 199e884a55

View File

@ -1,5 +1,107 @@
package main package main
func main() { import (
// TODO "errors" // 提供基本错误处理功能
"fmt" // 用于格式化输出
"os" // 提供操作系统功能
"strconv" // 用于字符串转换
)
// DivisionError 是一个自定义错误类型
// 它包含除法运算的被除数、除数和错误信息
type DivisionError struct {
dividend float64 // 被除数
divisor float64 // 除数
message string // 错误信息
}
// Error 方法实现了 error 接口
// 这使得 DivisionError 可以作为一个错误类型使用
func (e *DivisionError) Error() string {
return fmt.Sprintf("%s: %f / %f", e.message, e.dividend, e.divisor)
}
// divide 函数执行除法运算,并处理除数为零的情况
// 参数:
// - dividend: 被除数
// - divisor: 除数
//
// 返回:
// - float64: 除法结果
// - error: 可能的错误
func divide(dividend, divisor float64) (float64, error) {
if divisor == 0 {
// 当除数为零时,返回自定义错误
return 0, &DivisionError{
dividend: dividend,
divisor: divisor,
message: "cannot divide by zero",
}
}
return dividend / divisor, nil
}
// readConfig 函数读取配置文件并演示错误包装
// 使用 fmt.Errorf 和 %w 来包装底层错误
func readConfig(filename string) (string, error) {
data, err := os.ReadFile(filename)
if err != nil {
// 使用 %w 包装原始错误,保留错误链
return "", fmt.Errorf("failed to read config file: %w", err)
}
return string(data), nil
}
// parseAge 函数解析年龄字符串,展示多重错误处理
// 包含多个验证步骤,每步都可能产生不同的错误
func parseAge(age string) (int, error) {
// 检查空字符串
if age == "" {
return 0, errors.New("age cannot be empty")
}
// 将字符串转换为整数
n, err := strconv.Atoi(age)
if err != nil {
// 包装转换错误
return 0, fmt.Errorf("invalid age format: %w", err)
}
// 验证年龄范围
if n < 0 || n > 150 {
return 0, fmt.Errorf("age %d is out of valid range (0-150)", n)
}
return n, nil
}
func main() {
// 示例1演示自定义错误的使用
result, err := divide(10, 0)
if err != nil {
fmt.Printf("Division error: %v\n", err)
} else {
fmt.Printf("Result: %f\n", result)
}
// 示例2演示错误包装和错误类型断言
_, err = readConfig("nonexistent.txt")
if err != nil {
fmt.Printf("Config error: %v\n", err)
// 使用 os.IsNotExist 判断具体的错误类型
if os.IsNotExist(err) {
fmt.Println("The file does not exist")
}
}
// 示例3演示多重错误处理
ages := []string{"25", "-5", "abc", "200", ""}
for _, age := range ages {
parsedAge, err := parseAge(age)
if err != nil {
fmt.Printf("Error parsing age '%s': %v\n", age, err)
continue
}
fmt.Printf("Valid age: %d\n", parsedAge)
}
} }