Go语言无原生热编译,所谓“热编译”实为工具(如air或nodemon)监听文件变化后自动构建并重启进程;常见问题包括路径配置错误、未监听非.go文件、Windows文件锁及模板/配置未重载等。

Go 语言本身不支持热编译——它没有运行时解释器,改完 .go 文件不会自动生效,必须重新编译并替换正在运行的二进制。所谓“热编译”其实是开发阶段用工具监听文件变化、触发 go build + 启动新进程的自动化流程。
为什么改了代码没反应?先确认你用的是真热重载,不是假重启
常见错误现象:air 或 nodemon 启动后,改了 handler 但浏览器刷新还是旧内容;或者终端没打印 rebuild 日志,压根没触发编译。
- 你可能没在
go.mod所在的项目根目录运行air——air默认只扫描当前目录及子目录,且不递归进符号链接或vendor,如果主程序在cmd/myapp/main.go却在cmd/下执行,就监控不到 -
air.toml里root写了绝对路径(比如C:\projects\myapp),换机器或用户就失效;建议留空或填. -
build.cmd指向错误包,例如写成go build -o tmp/main .,但项目结构是模块化,真正入口是cmd/api/main.go,这时编译会成功,但跑的是旧main包 - 改的是
.html或.tmpl模板却没配include_ext,air默认只监听.go,得手动加进去
air 和 nodemon 怎么选?看你的场景和依赖
两者都能实现“保存即重启”,但机制和适用边界不同。
-
air是 Go 原生生态工具,用 Go 写的,启动快、无 Node.js 依赖,配置集中(.air.toml),适合标准 Go Web 项目;但它不处理 Windows 文件锁问题,高频保存时容易报access is denied,需配build.delay = 500缓冲 -
nodemon是通用监听器,靠--exec调用go run,省去编译步骤,适合小项目快速验证;但go run每次都全量解析+编译,比air的增量构建慢,且无法直接运行带 cgo 或需要交叉编译的项目 - 如果你用
echo、gin、fiber这类框架,air更稳;如果只是临时写个 CLI 工具或原型,nodemon --exec go run main.go更轻量
Windows 下常见报错:access is denied / The process cannot access the file
这是 Windows 独有坑:旧进程还没完全退出,新编译试图覆盖 tmp/main.exe,被系统锁定。
立即学习“go语言免费学习笔记(深入)”;
- 别用
go build -o main.exe .直接覆盖同名文件;强制走临时路径 + 时间戳或随机后缀,例如:go build -o ./tmp/main_$(date +%s).exe .(Linux/macOS);Windows 可用 PowerShell 替代:for /f %i in ('powershell -command "Get-Date -UFormat %s"') do go build -o ./tmp/main_%i.exe . - 更简单的方法:启用
air.toml中的build.delay = 600(单位毫秒),给旧进程释放句柄留出时间 - 确保
tmp/在.gitignore里,否则 Git 锁文件也可能干扰
真正容易被忽略的点是:热重载 ≠ 热加载。你改的是模板、配置、环境变量,这些内容是否被代码正确读取,和工具无关——air 只管重启,不管你的 os.Getenv 是不是读到了新值,也不管 template.ParseFiles 是不是重新加载了 HTML。这类逻辑必须自己编码保障,工具只负责“让新二进制跑起来”。


















