go要求本地包必须用模块路径导入,如“github.com/yourname/project/utils”,禁止使用./或../等文件系统路径;模块名决定所有导入路径前缀,需在go mod init时慎重选择。

本地包必须用模块路径导入,不能写 ./ 或 ../
Go 不允许用文件系统路径导入本地包,import "./utils" 或 import "../shared" 会直接报错 invalid import path。真正有效的导入路径是「模块名 + 目录相对路径」,比如你的 go.mod 第一行是 module github.com/yourname/project,那 project/utils 目录下的包就必须用 import "github.com/yourname/project/utils"。
常见错误包括:
- 在没运行
go mod init的目录下尝试导入 —— Go 根本不知道模块名,解析失败 - 包目录下没声明
package utils(首行必须是package xxx,且与导入路径末尾一致) - 把包放在
$GOPATH/src下却启用GO111MODULE=on—— Go 会忽略它,转而报no required module provides package
跨目录引用时,package 名不必等于目录名,但必须一致才安全
假设你有目录 internal/dbhelper,里面 dbhelper.go 首行写的是 package database,那你在代码里就得用 database.Connect() 调用,而不是 dbhelper.Connect()。但此时如果另一个包也声明 package database,就会冲突 —— Go 不允许同名包在同一作用域共存。
所以实际建议:
- 保持
package名和目录名完全一致,避免符号混淆 - 不要在多个子目录下重复使用同一个
package main—— 只有main.go才该用package main -
internal/下的包不能被其他模块 import,仅限当前模块内使用
想调试另一个本地模块?用 replace 指令,不是复制粘贴
当你同时开发主项目 github.com/you/app 和依赖库 github.com/you/lib,且后者还没发版,就别 go get 远程版本了。在主项目的 go.mod 末尾加一行:
replace github.com/you/lib => ../lib
注意:
-
../lib是相对于go.mod文件的位置,不是相对于.go文件 -
../lib目录下必须有合法的go.mod,且其中module行必须严格等于replace左侧的路径 - 执行
go mod tidy后,go list -m all应显示=>符号,表示重定向生效 - CI 构建前务必删掉
replace行,否则构建机器找不到../lib
go mod init 的模块名不是随便起的
模块名本质是导入路径的根前缀,一旦写进 go.mod,所有本地包导入都得从它开始拼。比如 go mod init myapp,那 ./pkg/auth 就得 import "myapp/pkg/auth";但如果以后要推送到 GitHub,改成 go mod init github.com/you/myapp,所有导入语句都得同步改 —— Go 不做自动映射。
所以一开始就要想清楚:
- 模块名最好用真实域名或 GitHub 路径,方便将来开源或迁移
- 别用纯短名如
foo,否则后期重构成本高 - 模块名大小写敏感,
MyApp和myapp是两个不同模块
最易被忽略的一点:模块名决定了整个项目的导入路径拓扑,改它等于重定义所有本地包的“地址”,不是只改一行 go.mod 就完事的。











