wavelet init

This commit is contained in:
ryan
2026-06-18 15:24:48 +08:00
parent d6a7011885
commit 99738bbc17
714 changed files with 139987 additions and 0 deletions
@@ -0,0 +1,71 @@
# 空白标识符模式
空白标识符 `_` 在 Go 中有多种用途:丢弃不需要的值、为副作用导入包、以及在编译时验证接口实现。
---
## 多重赋值
使用 `_` 丢弃多值表达式中不需要的值:
```go
if _, err := os.Stat(path); os.IsNotExist(err) {
fmt.Printf("%s does not exist\n", path)
}
```
### 绝不要随意丢弃错误
静默丢弃错误会引发空指针 panic:
```go
// 不好:忽略错误会在路径不存在时崩溃
fi, _ := os.Stat(path)
if fi.IsDir() { ... } // 空指针解引用
```
如果确实不需要错误,请记录原因:
```go
_ = logger.Sync() // 尽力刷新;错误不可操作
```
---
## 副作用导入
使用空白标识符仅为了 `init()` 副作用而导入包:
```go
import _ "net/http/pprof" // 注册 HTTP 处理器
import _ "image/png" // 注册 PNG 解码器
```
这通常用于注册驱动、编解码器或调试处理器,它们在 `init()` 期间将自己注册到注册表中。
---
## 接口实现检查
在编译时验证类型是否实现了接口,方法是将 nil 指针赋值给接口类型的空白标识符变量:
```go
var _ io.Writer = (*MyType)(nil)
```
如果 `*MyType` 不满足 `io.Writer`,这会产生编译错误,在运行时之前捕获缺失的方法。
**何时使用**:将此检查放在定义该类型的同一文件中,通常在类型声明之后。当类型必须满足另一个包中定义的接口时特别有用。
参见 [go-interfaces](../../go-interfaces/SKILL.md):接口满足检查,获取关于何时何地使用此模式的完整指导。
---
## 快速参考
| 模式 | 语法 |
|------|------|
| 丢弃值 | `_, err := f()` |
| 在 if 初始化中丢弃 | `if _, err := f(); err != nil { }` |
| 副作用导入 | `import _ "pkg"` |
| 接口检查 | `var _ Interface = (*Type)(nil)` |
@@ -0,0 +1,109 @@
# Switch 模式
Go `switch` 语句的详细模式,包括无表达式 switch、逗号 case、break 行为和带标签的 break。
---
## 无自动 Fallthrough
Go `switch` 的 case 默认**不会** fall through(与 C/Java 不同)。每个 case 主体隐式地 break。仅在明确需要时使用 `fallthrough` — 这在惯用 Go 中很少见。
```go
switch n {
case 1:
fmt.Println("one")
// 无 fallthrough — 下一个 case 不会执行
case 2:
fmt.Println("two")
}
```
---
## 无表达式 Switch
没有表达式的 `switch` 对 `true` 进行 switch。在将单个变量与多个条件进行比较时,用它来替代 if-else-if 链:
```go
func unhex(c byte) byte {
switch {
case '0' <= c && c <= '9':
return c - '0'
case 'a' <= c && c <= 'f':
return c - 'a' + 10
case 'A' <= c && c <= 'F':
return c - 'A' + 10
}
return 0
}
```
---
## 逗号分隔的 Case
多个值可以使用逗号共享一个 case 主体 — 不需要 `fallthrough`:
```go
func shouldEscape(c byte) bool {
switch c {
case ' ', '?', '&', '=', '#', '+', '%':
return true
}
return false
}
```
---
## 带标签的 Break
`switch` 中的 `break` 仅终止 switch,**不会**终止外层的 `for` 循环。使用标签来跳出循环:
```go
Loop:
for n := 0; n < len(src); n += size {
switch {
case src[n] < sizeOne:
break // 仅中断 switch
case src[n] < sizeTwo:
if n+1 >= len(src) {
break Loop // 跳出 for 循环
}
}
}
```
另一个常见模式 — 从 switch 内部中断 range 循环:
```go
Loop:
for _, v := range items {
switch v.Type {
case "done":
break Loop // 中断 for 循环
case "skip":
break // 仅中断 switch
}
}
```
**经验法则**:当 `for` 循环内有 `switch` 且需要从 case 中退出循环时,始终使用带标签的 break。
---
## 类型 Switch
关于类型 switch(`switch v := x.(type)`),参见 [go-interfaces](../../go-interfaces/SKILL.md):类型 Switch。
---
## 快速参考
| 模式 | 语法 |
|------|------|
| 无表达式 switch | `switch { case cond: }` |
| 逗号 case | `case 'a', 'b', 'c':` |
| 无 fallthrough | 默认行为;需要时使用 `fallthrough` 关键字 |
| 仅中断 switch | case 内使用 `break` |
| 中断外层循环 | 使用带标签的 `for` 和 `break Label` |