症状
构建失败并报 import cycle not allowed,并打印出形成环的链条,例如 package a imports b imports a。Go 按依赖顺序解析包,因此环没有合法顺序。它常在把一个类型移到原本就依赖原包的包之后出现,或当某个包的测试导入另一个又反向导入它的包时出现。
诊断
读取错误中的循环路径;用 go mod graph 判断依赖方向;把共享类型抽到独立包。
go list -deps ./... 2>&1 | head -40
根因
两个或多个包直接或间接互相依赖,编译器无法确定构建顺序。Go 在设计上禁止导入环。
修复
把共享类型或接口抽到双方都不依赖的独立包,或用接口反转依赖,使一方只依赖抽象。保持依赖图无环且方向指向抽象。
验证
重新构建并跑测试确认环已消除,并确认移动或反转后的类型在两侧行为正确。构建干净且测试通过即证明重构保留了行为。
常见陷阱
把类型塞进测试包来“解决”循环会让测试依赖生产代码之外的包,产生新的耦合。