用途
该技能用于在声明与初始化 Go 语言中的变量、常量、结构体和 map 时提供规范指导,包括 var 与 := 的取舍、利用 if-init 缩小变量作用域、复合字面量格式化,以及相关设计决策。
主要能力
var 与 := 的选择
根据上下文决定声明方式:
- 顶层声明:使用 var(始终),例如
var _s = F() - 局部变量且有值:使用 :=,例如
s := "foo" - 局部零值(有意为之):使用 var,例如
var filtered []int - 类型与表达式不同:使用带类型的 var,例如
var _e error = F()
分组声明
将相关的 var、const、type 放入带括号的块中;不相关的声明分入不同块。函数内部即使不相关,相邻变量也可分组:
var (
caller = c.name
format = "json"
timeout = 5 * time.Second
)
常量与 iota
枚举从 1 开始,使零值表示无效/未设置:
const (
Add Operation = iota + 1
Subtract
Multiply
)
当默认行为可接受时(例如 LogToStdout),从零开始。
变量作用域
当结果仅用于错误检查时,使用 if-init 限制作用域:
if err := os.WriteFile(name, data, 0644); err != nil {
return err
}
如果缩小作用域会导致更深的嵌套,或需要在 if 之外使用结果,则不要缩小作用域。仅在某函数内使用的常量可移入该函数。
结构体初始化
- 始终使用字段名(go vet 会强制检查);例外:字段不超过 3 个的测试表
- 省略零值字段,让 Go 设置默认值
- 零值结构体使用 var:
var user User,而非user := User{} - 使用
&T{}而非new(T):sptr := &T{Name: "bar"}
复合字面量格式化
外部包类型使用字段名;闭合括号的缩进与起始行对齐;在切片/map 字面量中省略重复类型名(gofmt -s)。
map 初始化
- 空 map、稍后填充:
make(map[K]V),例如m := make(map[string]int) - nil 声明:使用 var,例如
var m map[string]int - 初始化时固定条目:字面量,例如
m := map[string]int{"a": 1}
make() 可在视觉上区分“空但已初始化”与 nil。已知数量时使用尺寸提示。
原始字符串字面量
使用反引号字符串避免手工转义:
// Bad
wantError := "unknown name:\"test\""
// Good
wantError := `unknown name:"test"`
适用于正则、SQL、JSON 和多行文本。
优先使用 any 而非 interface{}
Go 1.18+ 中所有新代码使用 any 替代 interface{}。
避免遮蔽内建名称
不要将预声明标识符(error、string、len、cap、append、copy、new、make、close、delete、panic、recover、any、true、false、nil、iota)用作名称,可用 go vet 检测:
// Bad — 遮蔽内建标识符
var error string
// Good
var errorMessage string
资源路由
- references/SCOPE.md:在 var、:=、if-init 与缩窄变量作用域之间抉择时阅读
- references/IOTA.md:设计常量或类枚举值时阅读
- references/INITIALIZATION.md:初始化结构体、map、零值或指针时阅读
- references/LITERALS.md:复合字面量格式化与键字段取舍时阅读
- references/STRUCTS.md:设计或初始化结构体时阅读
- references/SHADOWING.md:声明可能遮蔽内建标识符或外层变量时阅读
适用场景
编写新的 Go 代码、审查声明与初始化风格、统一团队代码规范时均可使用。
限制
示例可能使用 any,因此需要 Go 1.18 及以上版本。关于该技能的收费、价格、平台等信息,资料中暂未提供。
相关技能
- 命名约定:见 go-naming
- 数据结构:见 go-data-structures
- 控制流作用域:见 go-control-flow
- 容量提示:见 go-performance