
go 不会自动包含同目录下所有 `.go` 文件;使用 `go run` 时必须显式列出所有参与编译的源文件(如 `go run main.go otherfile.go`),或用通配符 `*.go` 一次性指定。
在 Go 中,同一目录下的所有 .go 文件默认属于同一个包(只要它们声明了相同的 package 名,例如 package main),这确实意味着它们共享同一作用域——函数、变量、类型等可跨文件直接访问,无需 import 语句。但这有一个关键前提:这些文件必须同时参与编译。
你遇到的错误:
$ go run main.go # command-line-arguments ./main.go:4: undefined: foo
根本原因不是作用域问题,而是 go run main.go 仅编译并运行 main.go 这一个文件,otherfile.go 被完全忽略,因此其中定义的 foo() 函数对编译器不可见。
✅ 正确做法是显式包含所有相关源文件:
go run main.go otherfile.go
在 Linux/macOS 等支持 shell 通配符的系统中,更简洁的方式是:
go run *.go
该命令会自动展开为当前目录下所有 .go 文件(如 main.go、otherfile.go、utils.go 等),确保整个包完整编译。
⚠️ 注意事项:
- go run *.go 在 Windows 的 cmd 中不生效(需改用 PowerShell 或明确列出文件);
- 所有文件必须声明相同 package(如均为 package main),否则编译报错;
- 若项目结构变复杂(如含多个包、子目录),应使用模块化方式:在项目根目录执行 go mod init
,再通过 go run .(表示运行当前目录的主包)来统一管理。
? 小结:Go 的“包即目录”模型强调显式性——文件归属由 package 声明决定,而编译范围由命令行参数决定。理解这一点,就能避免常见的“undefined identifier”陷阱。










