如何在 Go 中跨文件调用同一包内的函数?

go 要求同一包下的多个源文件必须通过 `go build`(或 `go run .`)统一编译,而非单独运行单个 `.go` 文件;否则会因编译器未合并所有文件而导致“undefined”错误。

在 Go 中,即使两个文件同属 package main,它们也不会自动“可见”——Go 的编译模型以包(package)为单位进行构建

,而非以文件为单位。当你执行 go run main.go 时,Go 只编译并运行该文件,完全忽略 employee.go,因此 NewEmployee 函数未被定义,报错 undefined: NewEmployee。

✅ 正确做法是:在项目根目录(即包含 main.go 和 employee.go 的目录)下,使用以下任一命令:

go run .
# 或
go build && ./your-binary-name
# 或(推荐用于开发调试)
go run *.go  # ⚠️ 仅限临时使用,不推荐生产环境

其中 go run . 是最标准、最安全的方式:. 表示当前目录下的整个包,Go 会自动收集所有 .go 文件(排除 _test.go),按包名统一编译链接。

? 补充注意事项:

  • 所有文件必须声明相同的 package main(或其它一致的包名),且不能有语法错误;
  • 函数名首字母大写(如 NewEmployee)才对外可导出(虽在 main 包内非必需,但符合 Go 命名惯例);
  • employee.go 中 PrintEmployee 函数返回类型声明为 string,但函数体却写了 return "Hello world!" 却无返回值声明,实际应修正为:
    func PrintEmployee(p *Employee) string {
        return "Hello world!"
    }

    否则会编译失败(missing return at end of function)。

? 小技巧:可通过 go list -f '{{.GoFiles}}' . 查看当前包包含哪些源文件,确认 employee.go 是否已被识别。

总结:Go 不支持“隐式文件包含”,跨文件调用的核心前提是——用包级命令(如 go run .)触发完整包编译。养成 go run . 代替 go run xxx.go 的习惯,可避免绝大多数此类问题。