本文主要是介绍Go之errors.New和fmt.Errorf 的区别小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考...
error的基本用法
1. 获取错误信息
package main import ( "errors" "fmt" ) func main() { // 创建错误 err := errors.New("文件不存在") // 获取错误信息 errorMessage := err.Error() fmt.Println("错误信息:", errorMessage) // 输出: 错误信息: 文件不存在 // 直接打印错误 fmt.Println("直接打印:", err) // 输出: 直接打印: 文件不存在 }
2. 在条件判断中使用
package mahttp://www.chinasem.cnin import ( "errors" "fmt" ) func divide(a, b int) (int, error) { if b == 0 { return 0, errors.New("除数不能为零") } return a / b, nil } func main() { result, err := divide(10, 0) if err != nil { // 获取错误信息进行判断 if err.Error() == "除数不能为零" { fmt.Println("检测到除零错误") } // 打印错误信息 fmt.Println("错误:", err.Error()) return } fmt.Println("结果:", result) }
基本区别
1.函数签名
// errors.New - 只接受字符串 func New(text string) error // fmt.Errorf - 接受格式化字符串和参数 func Errorf(format string, a ...interface{}) error
2.使用场景
package main import ( "errors" "fmt" ) func main() { // errors.New - 简单静态错误 err1 := errors.New("文件不存在") fmt.Println(err1) // fmt.Errorf - 动态格式化错误 filename := "config.txt" err2 := fmt.Errorf("文件 %s 不存在", filename) fmt.Printf("phperr: %v \n", err.Error()) }
详细对比
1. 静态错误 vs 动态错误
package main import ( "errors" "fmt" ) // 使用 errors.New - 适合静态错误 var ( ErrNotFound = errors.New("记录未找到") ErrInvalidInput = errors.New("无效输入") ErrTimeout = errors.New("操作超时") ) // 使用 fmt.Errorf - 适合动态错误 func validateAge(age int) error { if age < 0 { return fmt.Errorf("年龄不能为负数: %d", age) } if age > 150 { return fmt.Errorf("年龄不能超过150岁: %d", age) } return nil } func main() { // 静态错误 fmt.Println(ErrNotFound) // 动态错误 err := validateAge(-5) fmt.Println(err) }
2. 错误比较
package main import ( "errors" "fmt" ) var ErrNotFound = errors.New("记录未找到") func main() { // errors.New 创建的错误可以用于比较 err1 := ErrNotFound err2 := ErrNotFound fmt.Println(err1 == err2) // true // fmt.Errorf 创建的错误每次都是新的 err3 := fmt.Errorf("记录未找到") err4 := fmt.Errorf("记录未找到") fmt.Println(err3 == err4) // false }
3. 错误包装
package main import ( "errors" "fmt" ) func processFile(filename string) error { // 模拟文件操作错误 originalErr := errors.New("权限不足") // 使用 fmt.Errorf 包装错误 return fmt.Errorf("处理文件 %s 失败: %v", filename, originalErr) } func main() { err := processFile("config.txt") fmt.Println(err) // 输出: 处理文件 config.txt 失败: 权限不足 }
实际应用场景
1. 使用 errors.New 的场景
package main import ( "errors" "fmt" ) // 定义包级别的错误常量 var ( ErrUserNotFound = errors.New("用户不存在") ErrInvalidPassword = errors.New("密码错误") ErrDatabaseConnection = errors.New("数据库连接失败") ) func authenticateUser(userID string, password string) error { if userID == "" { return ErrUserNotFound } if password == "" { return ErrInvalidPassword } // 验证逻辑... return nil } func main() { err := authenticateUser("", "123456") if err == ErrUserNotFound { fmt.Println("用户不存在") } else if err == ErrInvalidPassword { fmt.Println("密码错误") } }
2. 使用 fmt.Errorf 的场景
package main import ( "fmt" "strconv" ) func parseUserID(userIDStr string) (int, error) { userID, err := strconv.Atoi(userIDStr) if err != nil { return 0, fmt.Errorf("解析用户ID失败: %v", err) } if userID <= 0 { return 0, fmt.Errorf("用户ID必须大于0,当前值: %d", userID) } return userID, nil } func getUserInfo(userIDStr string) error { userID, err := parseUserID(userIDStr) if err != nil { return fmt.Errorf("获取用户信息失败: %v", err) } fmt.Printf("用户ID: %d\n", userID) return nil } func main() { err := getUserInfo("abc") if err != nil { fmt.Println("错误:", err) } }
自定义错误类型
1.基本用法
package main
import "fmt"
// 自定义错误类型
type ValidationError struct {
Field string
Message string
}
// 实现 Error() 方法
func (e *ValidationError) Error() string {
return fmt.Sprintf("验证失败: 字段 '%s' - %s", e.Field, e.Message)
}
func validateUser(name string) error {
if name == "" {
return &ValidationError{
Field: "name",
Message: "用户名不能为空",
}
}
return nil
}
func main() {
err := validateUser("")
if err != nil {
// 获取错误信息
fmt.Println("错DcBsXTjG误信息:", err.Error())
// 类型断言获取详细信息
if validationErr, ok := err.(*ValidationError); ok {
fmt.Printf("字段: %s, 消息: %s\n", validationErr.Field, validationErr.Message)
}
}
}
2.自定义错误类型示例
package main import ( "fmt" "time" ) // 1. 基础自定义错误类型 type ValidationError struct { Field string Message string Value interface{} } // 实现 error 接口 func (e *ValidationError) Error() string { return fmt.Sprintf("验证失败: 字段 '%s' 的值 '%v' - %s", e.Field, e.Value, e.Message) } // 2. 业务错误类型 type BusinessError struct { Code int Message string Time time.Time } func (e *BusinessError) Error() string { return fmt.Sprintf("[%d] %s (时间: %s)", e.Code, e.Message, e.Time.Format("2006-01-02 15:04:05")) } // 3. 网络错误类型 type NetworkError struct { URL string Status int Message string } func (e *NetworkError) Error() string { return fmt.Sprintf("网络请求失败: %s (状态码: %d) - %s", e.URL, e.Status, e.Message) } // 4. 复合错误类型 type CompositeError strujsct { Errors []error Context string } func (e *CompositeError) Error() string { if len(e.Errors) == 0 { return fmt.Sprintf("复合错误: %s", e.Context) } result := fmt.Sprintf("复合错误 [%s]:\n", e.Context) for i, err := range e.Errors { result += fmt.Sprintf(" %d. %s\n", i+1, err.Error()) } return result } // 5. 带错误码的错误类型 type CodedError struct { Code int Message string Details map[string]interface{} } func (e *CodedError) Error() string { if len(e.Details) == 0 { return fmt.Sprintf("[%d] %s", e.Code, e.Message) } return fmt.Sprintf("[%d] %s - 详情: %v", e.Code, e.Message, e.Details) } // 使用示例函数 func validateUser(name string, age int) error { if name == "" { return &ValidationError{ Field: "name", Message: "用户名不能为空", Value: name, } } if age < 0 || age > 150 { return &ValidationError{ Field: "age", Message: "年龄必须在 0-150 之间", Value: age, } } return nil } func processOrder(orderID string) error { if orderID == "" { return &BusinessError{ Code: 1001, Message: "订单ID不能为空", Time: time.Now(), } } // 模拟网络请求失败 if orderID == "invalid" { return &NetworkError{ URL: "https://api.example.com/orders/" + orderID, Status: 404, Message: "订单不存在", } } return nil } func complexOperation() error { var errors []error // 模拟多个操作 if err := validateUser("", 25); err != nil { errors = append(errors, err) } if err := processOrder(""); err != nil { errors = append(errors, err) } if len(errors) > 0 { return &CompositeError{ Errors: errors, Context: "用户注册操作", } } return nil } func main() { fmt.Println("=== 自定义错误类型示例 ===\n") // 1. 验证错误示例 fmt.Println("1. 验证错误:") if err := validateUser("", 25); err != nil { fmt.Printf(" %s\n", err.Error()) } if err := validateUser("张三", 200); err != nil { fmt.Printf(" %s\n", err.Error()) } // 2. 业务错误示例 fmt.Println("\n2. 业务错误:") if err := processOrder(""); err != nil { fmt.Printf(" %s\n", err.Error()) } // 3. 网络错误示例 fmt.Println("\n3. 网络错误:") if err := processOrder("invalid"); err != nil { fmt.Printf(" %s\n", err.Error()) } // 4. 复合错误示例 fmt.Println("\n4. 复合错误:") if err := complexOperation(); err != nil { fmt.Printf(" %s\n", err.Error()) } // 5. 带错误码的错误示例 fmt.Println("\n5. 带错误码的错误:") codedErr := &CodedError{ Code: 5001, Message: "数据库连接失败", Details: map[string]interface{}{ "host": "localhost:3306", "database": "users", "reason": "连接超时", }, } fmt.Printf(" %s\n", codedErr.Error()) // 6. 错误类型检查示例 fmt.Println("\n6. 错误类型检查:") err := validateUser("", 25) if validationErr, ok := err.(*ValidationError); ok { fmt.Printf(" 这是一个验证错误,字段: %s\n", validationErrpython.Field) } if businessErr, ok := err.(*BusinessError); ok { fmt.Printf(" 这是一个业务错误,错误码: %d\n", businessErr.Code) } }
到此这篇关于Go之errors.New 和 fmt.Errorf 的区别的文章就介绍到这了,更多相关Go errors.New 和 fmt.Errorf 内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!
这篇关于Go之errors.New和fmt.Errorf 的区别小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!