go中声明错误变量的标准写法是var err error,语义清晰且符合约定;函数调用时优先用f, err := os.open(),已声明则用err = json.unmarshal();禁用string或struct替代error类型,以支持errors.is/as及错误链;循环中需外层声明err避免作用域丢失。

Go里声明错误变量的标准写法
Go语言中错误信息统一用 error 接口类型表示,不是字符串也不是自定义结构体。声明变量时直接使用 error 作为类型,最常见的是初始化为 nil:
var err error
这种写法语义清晰:明确告诉阅读者这个变量将来要承载一个可能发生的错误,且初始状态是“无错误”。它比写 var err *errors.Error 或 var err string 更符合 Go 的错误处理约定。
函数返回错误时如何同步声明变量
调用可能返回错误的函数(比如 os.Open、json.Unmarshal)时,习惯上用短变量声明 := 同时接收返回值和错误:
f, err := os.Open("config.json")
但要注意:如果 err 在当前作用域已声明(比如外层已有 var err error),就不能再用 :=,否则会报错 no new variables on left side of :=。此时必须用 = 赋值:
- 外层已声明
var err error→ 内部用err = json.Unmarshal(data, &v) - 想复用同一个
err变量承接多个操作的错误 → 全部用=,避免意外创建新变量
为什么不能用 string 或自定义 struct 替代 error 类型
error 是接口,标准库和第三方包都依赖它做类型判断和错误链处理。如果你写成 var errMsg string:
- 无法和
errors.Is()、errors.As()配合使用 - 调用方无法用
if errors.Is(err, fs.ErrNotExist)判断底层错误类型 - 日志或调试时丢失堆栈(除非手动包装),而
fmt.Errorf("failed: %w", err)可保留原始错误链
所以哪怕只是临时存一个错误消息,也应走标准路径:err = fmt.Errorf("something went wrong"),而不是 errMsg = "something went wrong"。
声明 error 变量时容易忽略的作用域和重用问题
错误变量常被误放在 for 循环内部反复声明,导致每次迭代都新建一个变量,掩盖了前一次的错误:
for _, file := range files {
f, err := os.Open(file) // 每次都新声明 err
if err != nil {
log.Println(err)
continue
}
defer f.Close()
}
这段代码里,如果想在循环结束后检查是否所有文件都打开失败,就无法做到——因为 err 是局部的。正确做法是提前声明:
var err error
for _, file := range files {
f, err := os.Open(file) // 注意:这里仍用 :=,但外层 err 不参与接收
if err != nil {
log.Println(err)
continue
}
defer f.Close()
}
或者更稳妥地,把错误收集到切片里,或用 multierr 包合并。核心是:声明位置决定可访问范围,别让 err 消失得太早。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











