agents rename

This commit is contained in:
ryan
2026-08-04 11:40:32 +08:00
parent 21fb303ef2
commit 99f0f63b99
136 changed files with 1 additions and 2 deletions
@@ -0,0 +1,92 @@
# Must 函数
> **来源**:Uber 风格指南, Go 标准库约定
`Must` 函数包装一个可能失败的函数,在出错时 panic。**仅**在程序初始化阶段使用,因为失败意味着程序无法运行。
## 标准库示例
```go
// regexp.MustCompile 在模式无效时 panic
var validID = regexp.MustCompile(`^[a-z][a-z0-9-]{0,62}$`)
// template.Must 在模板解析失败时 panic
var tmpl = template.Must(template.ParseFiles("index.html"))
```
这些是安全的,因为它们在包初始化时运行——如果失败,程序无法正确运行。
## 何时使用 Must
```
这是在程序初始化期间调用的吗(包级 var、init、main 设置)?
├─ 是 → 失败是否不可恢复(配置、正则、模板)?
│ ├─ 是 → 使用 Must 是合适的
│ └─ 否 → 改为返回 error
└─ 否 → 绝不使用 Must——返回 error
```
### 适当的使用场景
- **包级 `var`**:编译正则表达式、解析模板、加载必需的配置
- **`init()` 或 `main()` 早期**:设置程序运行所必需的资源
- **测试辅助函数**:测试中优先使用 `t.Fatal`,但 Must 在测试 fixture 中是可以接受的
### 绝不使用 Must 的场景
- 运行时请求处理
- 用户提供的输入
- 可能合理失败的网络或文件操作
- 程序启动后调用的任何代码
## 编写 Must 函数
遵循命名约定 `MustX`,其中 `X` 是可能失败的函数名:
```go
func MustParseConfig(path string) *Config {
cfg, err := ParseConfig(path)
if err != nil {
panic(fmt.Sprintf("parsing config %s: %v", path, err))
}
return cfg
}
```
### 指南
- **命名**:`Must` 前缀 + 可能失败的函数名(例如 `MustParse`、`MustNew`、`MustCompile`)
- **Panic 消息**:包含输入和错误信息以便调试
- **文档**:始终记录函数在出错时会 panic
```go
// MustParseConfig 解析路径处的配置文件。
// 如果文件无法读取或包含无效配置,则会 panic。
func MustParseConfig(path string) *Config { ... }
```
### 泛型 Must 辅助函数
对于一次性使用,泛型 Must 辅助函数可以避免样板代码:
```go
func Must[T any](v T, err error) T {
if err != nil {
panic(err)
}
return v
}
// 在包级别使用
var cfg = Must(ParseConfig("app.yaml"))
```
## 与 Panic/Recover 的关系
Must 函数是对 `panic` 的受控使用。它们应该:
- 仅在初始化期间运行(因此不需要 recover)
- 产生清晰、可操作的 panic 消息
- 绝不在可以返回 error 的场景中使用
完整的 panic/recover 模式请参见 [PANIC-RECOVER.md](PANIC-RECOVER.md)。