"Undefined" function in Go: how to make files work together without losing your mind
\n\nImagine: you're writing a Go program, splitting the code into logical files (e.g., main.go and helper.go), run go run main.go — and the compiler gives you an icy: "undefined: MyFunction". Sound familiar? This question is one of the most popular on Stack Overflow (thousands of views!), and today we'll break it down once and for all.
Why does Go, which is famous for its simplicity, suddenly not see a function from a neighboring file? It's not magic, but strict code organization rules. Let's go through all the scenarios — from the classic beginner mistake to proper module handling.
\n\nScenario 1: Classic — forgot to specify all files when running
\n\nThe most common case. You write:
\n\n// main.go\npackage main\n\nfunc main() {\n printHello() // Error: undefined: printHello\n}\n\n\n// helper.go\npackage main\n\nimport "fmt"\n\nfunc printHello() {\n fmt.Println("Hello!")\n}\n\n\nAnd you only run go run main.go. Go doesn't see helper.go because you didn't explicitly specify it. The correct solution:
go run main.go helper.go\n// or simpler:\ngo run .\n\n\nWhy is that? Go does not automatically scan the directory — you must list all files of the package. The go run . command runs the entire current folder as a single package.
Scenario 2: Different packages — invisibility by default
\n\nAnother popular pitfall is trying to call a function from another package without importing and exporting.
\n\n// main.go\npackage main\n\nfunc main() {\n helper.DoSomething() // Error: undefined: helper\n}\n\n\n// helper/helper.go\npackage helper\n\nfunc DoSomething() {\n // ...\n}\n\n\nThere are two problems here:
\n- \n
- The files are in different packages (
mainandhelper). \n - The
DoSomethingfunction is not exported (starts with a lowercase letter). \n
Corrected version:
\n\n// main.go\npackage main\n\nimport "yourmodule/helper"\n\nfunc main() {\n helper.DoSomething() // Works!\n}\n\n\n// helper/helper.go\npackage helper\n\nfunc DoSomething() { // Capital letter!\n // ...\n}\n\n\nRemember: In Go, only entities with a capital letter are exported. A lowercase letter means private to the package.
\n\nScenario 3: Problems with modules and GOPATH
\n\nIf you're using the old style (GOPATH) or initialized the module incorrectly, Go might not find your files even in the same folder.
\n\nCheck:
\n- \n
- Is there a
go.modfile in the project root? If not, create one:go mod init module_name. \n - Are you storing the project inside
$GOPATH/srcwithout a module? This is legacy mode that can cause confusion. \n - Make sure all files in the folder have the same
package(except test files with the_testsuffix). \n
Example of a correct structure:
\n\nmyproject/\n├── go.mod # module myproject\n├── main.go # package main\n└── helper.go # package main\n\n\nScenario 4: File names with underscores and test files
\n\nGo ignores files starting with _ or . (e.g., _hidden.go). Files with the _test.go suffix are only built when running tests (go test). If you accidentally named a working file as helper_test.go — its functions will not be visible in the main code.
Scenario 5: Circular dependencies
\n\nSometimes the "undefined" error can be a consequence of circular imports. For example, package A imports B, and B imports A. Go forbids such cycles and m