Função "Indefinida" em Go: como fazer os arquivos se entenderem e não enlouquecer
\n\nImagine: você está escrevendo um programa em Go, divide o código em arquivos lógicos (por exemplo, main.go e helper.go), executa go run main.go — e o compilador exibe um gelado: "undefined: MyFunction". Familiar? Esta pergunta é uma das mais populares no Stack Overflow (milhares de visualizações!), e hoje vamos entendê-la de uma vez por todas.
Por que o Go, que é famoso por sua simplicidade, de repente não vê uma função de um arquivo vizinho? Não é mágica, mas sim regras estritas de organização de código. Vamos percorrer todos os cenários — desde o erro clássico de iniciante até o trabalho correto com módulos.
\n\nCenário 1: Clássico — esqueceu de especificar todos os arquivos ao executar
\n\nO caso mais comum. Você escreve:
\n\n// main.go\npackage main\n\nfunc main() {\n printHello() // Erro: undefined: printHello\n}\n\n\n// helper.go\npackage main\n\nimport "fmt"\n\nfunc printHello() {\n fmt.Println("Hello!")\n}\n\n\nE executa apenas go run main.go. O Go não vê helper.go, porque você não o especificou explicitamente. A solução correta:
go run main.go helper.go\n// ou mais simples:\ngo run .\n\n\nPor que isso acontece? O Go não escaneia o diretório automaticamente — você deve listar todos os arquivos do pacote. O comando go run . executa toda a pasta atual como um único pacote.
Cenário 2: Pacotes diferentes — invisibilidade por padrão
\n\nOutra armadilha popular é tentar chamar uma função de outro pacote sem importação e exportação.
\n\n// main.go\npackage main\n\nfunc main() {\n helper.DoSomething() // Erro: undefined: helper\n}\n\n\n// helper/helper.go\npackage helper\n\nfunc DoSomething() {\n // ...\n}\n\n\nAqui há dois problemas:
\n- \n
- Os arquivos estão em pacotes diferentes (
mainehelper). \n - A função
DoSomethingnão foi exportada (começa com letra minúscula). \n
Versão corrigida:
\n\n// main.go\npackage main\n\nimport "yourmodule/helper"\n\nfunc main() {\n helper.DoSomething() // Funciona!\n}\n\n\n// helper/helper.go\npackage helper\n\nfunc DoSomething() { // Letra maiúscula!\n // ...\n}\n\n\nLembre-se: Em Go, apenas entidades com letra maiúscula são exportadas. Letra minúscula significa privado para o pacote.
\n\nCenário 3: Problemas com módulos e GOPATH
\n\nSe você está usando o estilo antigo (GOPATH) ou inicializou o módulo incorretamente, o Go pode não encontrar seus arquivos, mesmo na mesma pasta.
\n\nVerifique:
\n- \n
- Existe um arquivo
go.modna raiz do projeto? Se não, crie:go mod init nome_do_modulo. \n - Você não está armazenando o projeto dentro de
$GOPATH/srcsem um módulo? Isso é um modo legado que pode causar confusão. \n - Certifique-se de que todos os arquivos na pasta têm o mesmo
package(exceto arquivos de teste com o sufixo_test). \n
Exemplo de estrutura correta:
\n\nmyproject/\n├── go.mod # module myproject\n├── main.go # package main\n└── helper.go # package main\n\n\nCenário 4: Nomes de arquivos com sublinhados e arquivos de teste
\n\nO Go ignora arquivos que começam com _ ou . (por exemplo, _hidden.go). E arquivos com o sufixo _test.go são compilados apenas ao executar testes (go test). Se você acidentalmente nomeou um arquivo de trabalho como helper_test.go — suas funções não serão visíveis no código principal.
Cenário 5: Dependências cíclicas
\n\nÀs vezes, o erro "undefined" pode ser consequência de uma importação cíclica. Por exemplo, o pacote A importa B, e B importa A. O Go proíbe esses ciclos e m