Understanding the Error
The undefined variable error occurs during compilation:
./main.go:10:5: undefined: myVariable
./main.go:15:8: undefined: someFunctionThis error means Go cannot find a declaration for the name you're using. Unlike some languages, Go doesn't allow using undeclared variables.
Common Causes and Solutions
Cause 1: Variable Not Declared
Problem code:
``go
func main() {
count = 10 // Error: undefined: count
fmt.Println(count)
}
Solution - Declare the variable:
``go
func main() {
var count int = 10
// or
count := 10 // Short declaration
fmt.Println(count)
}
Cause 2: Variable Outside Scope
Problem code:
``go
func main() {
if true {
inner := "hello"
}
fmt.Println(inner) // Error: undefined: inner
}
Solution - Adjust scope: ```go func main() { var inner string if true { inner = "hello" } fmt.Println(inner) // Works }
// Or if you need the value outside func main() { inner := "" if true { inner = "hello" } fmt.Println(inner) } ```
Cause 3: Typo in Variable Name
Problem code:
``go
func main() {
userName := "Alice"
fmt.Println(username) // Error: undefined: username (case mismatch)
}
Solution - Fix the typo:
``go
func main() {
userName := "Alice"
fmt.Println(userName) // Correct
}
Cause 4: Package-level Variable Not Exported
Problem code: ```go // config/config.go package config
var defaultPort = 8080 // Lowercase = unexported
// main.go package main
import "myapp/config"
func main() { fmt.Println(config.defaultPort) // Error: undefined } ```
Solution 1 - Export the variable: ```go // config/config.go package config
var DefaultPort = 8080 // Uppercase = exported
// main.go package main
import "myapp/config"
func main() { fmt.Println(config.DefaultPort) // Works } ```
Solution 2 - Provide a getter function: ```go // config/config.go package config
var defaultPort = 8080
func GetDefaultPort() int { return defaultPort }
// main.go package main
func main() { fmt.Println(config.GetDefaultPort()) } ```
Cause 5: Variable in Different Package
Problem code: ```go // user/user.go package user
type User struct { Name string }
// main.go package main
func main() { u := User{Name: "Alice"} // Error: undefined: User } ```
Solution - Import the package: ```go package main
import "myapp/user"
func main() { u := user.User{Name: "Alice"} fmt.Println(u.Name) } ```
Cause 6: Short Declaration Outside Function
Problem code: ```go package main
count := 10 // Error: syntax error: non-declaration statement outside function body
func main() { fmt.Println(count) } ```
Solution - Use var at package level: ```go package main
var count = 10 // Package-level declaration must use 'var'
func main() { fmt.Println(count) } ```
Cause 7: Assignment Instead of Declaration
Problem code:
``go
func main() {
var name string
name := "Alice" // Error: no new variables on left side of :=
}
Solution - Use assignment:
``go
func main() {
var name string
name = "Alice" // Assignment, not declaration
}
Cause 8: Cyclic Import
Problem code: ```go // package a/a.go package a import "myapp/b" var A = "hello"
// package b/b.go package b import "myapp/a" var B = a.A // Error: undefined during compilation ```
Solution - Restructure packages: ```go // package common/common.go package common var SharedValue = "hello"
// package a/a.go package a import "myapp/common" var A = common.SharedValue
// package b/b.go package b import "myapp/common" var B = common.SharedValue ```
Quick Diagnosis Commands
Check for Typos
```bash # Use go vet to find issues go vet ./...
# Use staticcheck for deeper analysis go install honnef.co/go/tools/cmd/staticcheck@latest staticcheck ./... ```
IDE Assistance
Most Go IDEs highlight undefined variables. Use:
# gopls (Language Server) diagnostics
go install golang.org/x/tools/gopls@latest
gopls check main.goModule Issues
Sometimes the error is due to missing module:
```bash # Ensure dependencies are downloaded go mod tidy go mod download
# Check imports go list -m all ```
Common Patterns to Avoid
Shadowing Variables
func main() {
name := "outer"
if true {
name := "inner" // New variable, shadows outer!
fmt.Println(name) // "inner"
}
fmt.Println(name) // "outer"
}This is legal but confusing. Use different names:
func main() {
name := "outer"
if true {
innerName := "inner"
fmt.Println(innerName)
}
fmt.Println(name)
}Unused Import
import (
"fmt"
"os" // Error: imported and not used
)Either use or remove:
```go import ( "fmt" )
// Or use blank import for side effects import ( _ "github.com/lib/pq" // Driver registers itself ) ```
Verification
After fixing, verify with:
```bash # Compile check go build ./...
# Run tests go test ./...
# Format code go fmt ./... ```