自定义错误类型
This commit is contained in:
parent
3c981f9315
commit
199e884a55
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user