This guide covers common issues encountered while learning Go, based on typical problems students face in the Learn Go course. Each section includes the error, explanation, and solution.
var name stringfunc main() { name := "Alice" // Creates NEW variable, doesn't assign setName()}func setName() { fmt.Println(name) // Prints empty string!}
:= always creates a new variable. Use = to assign to existing variables.
items := []string{"a", "b", "c"}var ptrs []*stringfor _, item := range items { ptrs = append(ptrs, &item) // Bug: all point to same variable!}// All pointers point to "c"for _, ptr := range ptrs { fmt.Println(*ptr) // Prints "c" three times}
Solution:
items := []string{"a", "b", "c"}var ptrs []*stringfor _, item := range items { item := item // Create new variable ptrs = append(ptrs, &item)}// Or better:for i := range items { ptrs = append(ptrs, &items[i])}
The range loop reuses the same variable. If you take its address, you’ll get unexpected results.
m := map[string]int{ "a": 1, "b": 2, "c": 3,}for k, v := range m { fmt.Println(k, v) // Order is random!}
Map iteration order is intentionally randomized in Go. Don’t rely on it.
Solution for ordered iteration:
// Get keys and sort themkeys := make([]string, 0, len(m))for k := range m { keys = append(keys, k)}sort.Strings(keys)// Iterate in orderfor _, k := range keys { fmt.Println(k, m[k])}
var i interface{} = "hello"num := i.(int) // panic: interface conversion: interface is string, not int
Solution:
var i interface{} = "hello"// Safe type assertionif num, ok := i.(int); ok { fmt.Println("Number:", num)} else { fmt.Println("Not an int")}// Or use type switchswitch v := i.(type) {case int: fmt.Println("Int:", v)case string: fmt.Println("String:", v)default: fmt.Println("Unknown type")}
var counter intfunc increment() { counter++ // Not atomic!}func main() { for i := 0; i < 1000; i++ { go increment() } time.Sleep(time.Second) fmt.Println(counter) // Might not be 1000!}
Solutions:
var ( counter int mu sync.Mutex)func increment() { mu.Lock() counter++ mu.Unlock()}
// Use %#v for detailed outputfmt.Printf("%#v\n", myStruct) // Shows field names and values// Show typesfmt.Printf("%T\n", variable)// Show memory addressesfmt.Printf("%p\n", &variable)