错误基础 #
一、error接口 #
1.1 接口定义 #
go
type error interface {
Error() string
}
1.2 创建错误 #
go
import "errors"
err := errors.New("something went wrong")
1.3 fmt.Errorf #
go
err := fmt.Errorf("failed to open file: %s", filename)
二、错误检查 #
2.1 基本检查 #
go
result, err := someFunction()
if err != nil {
return err
}
2.2 nil检查 #
go
if err != nil {
fmt.Println("Error:", err)
}
2.3 错误处理模式 #
go
func doSomething() error {
if err := step1(); err != nil {
return err
}
if err := step2(); err != nil {
return err
}
return nil
}
三、错误传播 #
3.1 返回错误 #
go
func readFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
return data, nil
}
3.2 添加上下文 #
go
func processFile(path string) error {
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read %s: %w", path, err)
}
return nil
}
四、实际应用 #
4.1 文件操作 #
go
func openFile(path string) (*os.File, error) {
f, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("open file: %w", err)
}
return f, nil
}
4.2 HTTP请求 #
go
func fetch(url string) ([]byte, error) {
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("fetch %s: %w", url, err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status %d", resp.StatusCode)
}
return io.ReadAll(resp.Body)
}
4.3 数据库操作 #
go
func queryUser(db *sql.DB, id int) (*User, error) {
row := db.QueryRow("SELECT id, name FROM users WHERE id = ?", id)
var user User
err := row.Scan(&user.ID, &user.Name)
if err != nil {
if err == sql.ErrNoRows {
return nil, fmt.Errorf("user %d not found", id)
}
return nil, fmt.Errorf("query user: %w", err)
}
return &user, nil
}
五、最佳实践 #
5.1 早返回 #
go
func process(data []byte) error {
if len(data) == 0 {
return errors.New("empty data")
}
// 处理...
return nil
}
5.2 添加上下文 #
go
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
5.3 不要忽略错误 #
go
// 不好
data, _ := os.ReadFile(path)
// 好
data, err := os.ReadFile(path)
if err != nil {
return err
}
六、总结 #
错误处理要点:
| 方法 | 说明 |
|---|---|
| errors.New | 创建简单错误 |
| fmt.Errorf | 格式化错误 |
| %w | 包装错误 |
关键点:
- error接口:Error() string方法
- 错误检查:if err != nil
- 错误传播:返回错误给调用者
- 添加上下文:使用fmt.Errorf
- 不要忽略:始终处理错误
准备好学习自定义错误了吗?让我们进入下一章!
最后更新:2026-03-26