
Go 要求所有非标准库包必须使用完整、唯一的导入路径(如 github.com/myname/hello/vector),而非相对路径;错误源于未遵循 $GOPATH/src 下的全路径导入约定,且 go run 不会自动推导本地子目录为根。
go 要求所有非标准库包必须使用完整、唯一的导入路径(如 `github.com/myname/hello/vector`),而非相对路径;错误源于未遵循 `$gopath/src` 下的全路径导入约定,且 `go run` 不会自动推导本地子目录为根。
在 Go 中,包导入机制不支持相对路径或简写路径(如 "vector"),它严格依赖 Go 工作区(workspace)的目录结构和完整的、可唯一标识的导入路径。你遇到的错误:
Can't find package "vector" in any of:
C:\Go\src\vendor\vector (vendor tree)
C:\Go\src\vertex (from $GOROOT)
C:\Go\src\github.com\myname\src\vertex (from $GOPATH)
关键线索在于最后一行:github.com\myname\src\vertex —— 这说明 Go 尝试在 $GOPATH/src 下拼接 github.com/myname/src/vector,而实际路径却是 github.com/myname/hello/vector。问题根源在于:
- ✅ 你的项目结构本身合理:$GOPATH/src/github.com/myname/hello/ 是标准布局;
- ❌ 但 import "vector" 是非法的:Go 不会根据当前文件位置(如 main.go 所在目录)动态解析子包,也不会将 hello/ 视为根路径;
- ❌ go run main.go 的执行位置不影响导入解析逻辑 —— 导入始终基于 $GOPATH/src 或模块根,而非当前工作目录。
✅ 正确做法是:始终使用从 $GOPATH/src 开始的完整路径作为导入路径。
即在 main.go 中应写为:
package main
import (
"fmt"
"github.com/myname/hello/vector" // ✅ 完整、唯一、可定位
)
func main() {
v := vector.New(1, 2, 3)
fmt.Println(v.String())
}
同时确保 vector/vector.go 正确定义了包名(非 main):
// vector/vector.go
package vector
import "fmt"
type Vec3 struct{ X, Y, Z float64 }
func New(x, y, z float64) *Vec3 {
return &Vec3{x, y, z}
}
func (v *Vec3) String() string {
return fmt.Sprintf("(%.1f, %.1f, %.1f)", v.X, v.Y, v.Z)
}
⚠️ 注意事项:
- 不要手动修改 $GOPATH/src/github.com/myname/src/... —— src 是 $GOPATH 的固定子目录,不是你项目名的一部分;
- 若使用 Go 1.11+,推荐启用 Go Modules(go mod init github.com/myname/hello),此时可脱离 $GOPATH,但仍需用完整模块路径导入(如 github.com/myname/hello/vector),且 go run . 比 go run main.go 更安全;
- go run hello.go 是错误命令(应为 go run main.go),且仅运行单文件;若含子包,必须用 go run . 或指定全部文件(go run main.go vector/*.go),但强烈建议使用标准构建方式(go build / go run .)。
总结:Go 的包系统设计强调可重现性与全局唯一性,因此拒绝模糊路径。坚持“路径即导入名”原则——你的目录在哪,就用哪段路径导入。这是 Go 工程化健壮性的基石,而非限制。










