Función «Indefinida» en Go: cómo hacer que los archivos se lleven bien y no volverse loco
\n\nImagina: estás escribiendo un programa en Go, divides el código en archivos lógicos (por ejemplo, main.go y helper.go), ejecutas go run main.go — y el compilador te muestra un frío: «undefined: MyFunction». ¿Te suena? Esta pregunta es una de las más populares en Stack Overflow (¡miles de visitas!), y hoy la analizaremos de una vez por todas.
¿Por qué Go, que es famoso por su simplicidad, de repente no ve una función de un archivo vecino? No es magia, sino reglas estrictas de organización del código. Repasemos todos los escenarios, desde el error clásico de principiante hasta el trabajo correcto con módulos.
\n\nEscenario 1: Clásico — olvidaste especificar todos los archivos al ejecutar
\n\nEl caso más común. Escribes:
\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("¡Hola!")\n}\n\n\nY ejecutas solo go run main.go. Go no ve helper.go porque no lo especificaste explícitamente. La solución correcta:
go run main.go helper.go\n// o más simple:\ngo run .\n\n\n¿Por qué? Go no escanea el directorio automáticamente — debes enumerar todos los archivos del paquete. El comando go run . ejecuta toda la carpeta actual como un paquete único.
Escenario 2: Diferentes paquetes — invisibilidad por defecto
\n\nOtra trampa popular es intentar llamar a una función de otro paquete sin importar y exportar.
\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\nAquí hay dos problemas:
\n- \n
- Los archivos están en diferentes paquetes (
mainyhelper). \n - La función
DoSomethingno está exportada (comienza con minúscula). \n
Versión corregida:
\n\n// main.go\npackage main\n\nimport "tumodulo/helper"\n\nfunc main() {\n helper.DoSomething() // ¡Funciona!\n}\n\n\n// helper/helper.go\npackage helper\n\nfunc DoSomething() { // ¡Mayúscula!\n // ...\n}\n\n\nRecuerda: En Go solo se exportan las entidades con letra mayúscula. Minúscula significa privado para el paquete.
\n\nEscenario 3: Problemas con módulos y GOPATH
\n\nSi usas el estilo antiguo (GOPATH) o inicializaste el módulo incorrectamente, Go puede no encontrar tus archivos incluso en la misma carpeta.
\n\nVerifica:
\n- \n
- ¿Hay un archivo
go.moden la raíz del proyecto? Si no, créalo:go mod init nombre_del_módulo. \n - ¿No estás guardando el proyecto dentro de
$GOPATH/srcsin un módulo? Este es un modo heredado que puede causar confusión. \n - Asegúrate de que todos los archivos en la carpeta tengan el mismo
package(excepto los archivos de prueba con el sufijo_test). \n
Ejemplo de estructura correcta:
\n\nmiproyecto/\n├── go.mod # module miproyecto\n├── main.go # package main\n└── helper.go # package main\n\n\nEscenario 4: Nombres de archivos con guiones bajos y archivos de prueba
\n\nGo ignora los archivos que comienzan con _ o . (por ejemplo, _oculto.go). Y los archivos con el sufijo _test.go solo se compilan al ejecutar pruebas (go test). Si accidentalmente nombraste un archivo de trabajo como helper_test.go, sus funciones no serán visibles en el código principal.
Escenario 5: Dependencias cíclicas
\n\nA veces, el error «undefined» puede ser consecuencia de una importación cíclica. Por ejemplo, el paquete A importa B, y B importa A. Go prohíbe estos ciclos y m