Avoid These Hidden Go Pitfalls: Octal Literals, Integer Overflow, Float Comparison, Slices & Maps

This article reveals thirteen subtle Go programming mistakes—from octal literals and integer overflow to floating‑point comparison, slice length vs. capacity, map initialization, and value copying—providing clear explanations, real‑world analogies, and concrete best‑practice code fixes to prevent bugs and performance issues.

FunTester
FunTester
FunTester
Avoid These Hidden Go Pitfalls: Octal Literals, Integer Overflow, Float Comparison, Slices & Maps

Go developers often encounter hard‑to‑spot bugs that can cause logical errors or performance bottlenecks. This guide enumerates thirteen common mistakes (errors 17‑29), explains why they occur, and offers best‑practice solutions with runnable code examples.

Error 17: Octal Literal Confusion

Numeric literals starting with 0 are interpreted as octal, which can lead to unexpected values.

package main

import "fmt"

func main() {
    number := 0755 // octal literal
    fmt.Printf("FunTester: permission number is %d
", number)
}

Use the 0o prefix to make octal literals explicit.

package main

import "fmt"

func main() {
    number := 0o755 // explicit octal
    fmt.Printf("FunTester: permission number is %d
", number)
}

Error 18: Ignoring Integer Overflow

Adding two large int values can overflow, producing incorrect results.

package main

import "fmt"

func calculateFunTester(a, b int) int { return a + b }

func main() {
    a := 2147483647 // max int32
    b := 1
    result := calculateFunTester(a, b)
    fmt.Printf("FunTester: result is %d
", result) // overflow
}

Detect overflow by checking sign changes before returning.

package main

import (
    "errors"
    "fmt"
)

func calculateFunTester(a, b int) (int, error) {
    result := a + b
    if (a > 0 && b > 0 && result < 0) || (a < 0 && b < 0 && result > 0) {
        return 0, errors.New("FunTester: integer overflow")
    }
    return result, nil
}

func main() {
    a := 2147483647
    b := 1
    result, err := calculateFunTester(a, b)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("FunTester: result is %d
", result)
}

Error 19: Floating‑Point Comparison Pitfalls

Direct equality checks on floating‑point numbers are unreliable due to representation errors.

package main

import "fmt"

func main() {
    a := 0.1
    b := 0.2
    sum := a + b
    if sum == 0.3 {
        fmt.Println("FunTester: equal")
    } else {
        fmt.Println("FunTester: not equal") // actually prints this
    }
}

Compare using a tolerance (delta) instead of direct equality.

package main

import (
    "fmt"
    "math"
)

func main() {
    a := 0.1
    b := 0.2
    sum := a + b
    delta := math.Abs(sum - 0.3)
    if delta < 1e-9 {
        fmt.Println("FunTester: equal via delta")
    }
}

Error 20: Misunderstanding Slice Length and Capacity

len

returns the number of elements, while cap returns the underlying array capacity; ignoring capacity can hurt performance.

package main

import "fmt"

func main() {
    s := []int{1, 2, 3}
    fmt.Printf("FunTester: len=%d, cap=%d
", len(s), cap(s))
}

Initialize slices with explicit length and capacity using make.

package main

import "fmt"

func main() {
    s := make([]int, 3, 5) // len=3, cap=5
    fmt.Printf("FunTester: len=%d, cap=%d
", len(s), cap(s))
}

Error 21: Inefficient Slice Initialization

Repeated append without pre‑allocating capacity triggers many allocations.

package main

import "fmt"

func main() {
    var s []int
    for i := 0; i < 1000; i++ {
        s = append(s, i)
    }
    fmt.Printf("FunTester: len=%d, cap=%d
", len(s), cap(s))
}

Pre‑set capacity to avoid re‑allocations.

package main

import "fmt"

func main() {
    s := make([]int, 0, 1000) // capacity 1000
    for i := 0; i < 1000; i++ {
        s = append(s, i)
    }
    fmt.Printf("FunTester: len=%d, cap=%d
", len(s), cap(s))
}

Error 22: Nil vs. Empty Slice Confusion

A nil slice and an empty slice behave differently; treating them uniformly prevents bugs.

package main

import "fmt"

func main() {
    var nilSlice []int
    emptySlice := []int{}
    fmt.Println("nilSlice == nil?", nilSlice == nil)
    fmt.Println("emptySlice == nil?", emptySlice == nil)
}

Return an empty slice instead of nil when a slice is expected.

package main

import "fmt"

func getFunTesterSlice() []int { return []int{} }

func main() {
    slice := getFunTesterSlice()
    fmt.Println("FunTester: slice empty?", len(slice) == 0)
}

Error 23: Accessing Slice Without Empty Check

Indexing a nil or empty slice causes a runtime panic.

package main

import "fmt"

func main() {
    var s []int
    if len(s) > 0 && s[0] == 10 {
        fmt.Println("FunTester: first element is 10")
    } else {
        fmt.Println("FunTester: slice is empty")
    }
}

Error 24: Incomplete Slice Copy

Copying to a destination slice that is too short truncates data.

package main

import "fmt"

func main() {
    original := []int{1, 2, 3}
    copySlice := make([]int, 2)
    copy(copySlice, original) // copies only first two elements
    fmt.Printf("FunTester: copySlice = %v
", copySlice)
}

Allocate the destination with the same length as the source.

package main

import "fmt"

func main() {
    original := []int{1, 2, 3}
    copySlice := make([]int, len(original))
    copy(copySlice, original)
    fmt.Printf("FunTester: copySlice = %v
", copySlice)
}

Error 25: Slice Append Side‑Effects

Appending to a slice inside a function may modify a shared underlying array, leaving the caller unchanged.

package main

import "fmt"

func modifySlice(s []int) {
    s = append(s, 4)
    fmt.Println("FunTester: modifySlice internal s =", s)
}

func main() {
    s := []int{1, 2, 3}
    modifySlice(s)
    fmt.Println("FunTester: main s =", s) // unchanged
}

Create an explicit copy before modifying.

package main

import "fmt"

func modifySlice(s []int) {
    copied := make([]int, len(s))
    copy(copied, s)
    copied = append(copied, 4)
    fmt.Println("FunTester: modifySlice internal copied =", copied)
}

func main() {
    s := []int{1, 2, 3}
    modifySlice(s)
    fmt.Println("FunTester: main s =", s)
}

Error 26: Slice‑Related Memory Leak

Keeping references to a larger underlying array via a subslice prevents the garbage collector from freeing memory.

package main

import "fmt"

func main() {
    nodes := []*int{new(int), new(int), new(int)}
    subslice := nodes[:2]
    fmt.Printf("FunTester: subslice = %v
", subslice)
}

Explicitly nil out elements that are no longer needed.

package main

import "fmt"

func main() {
    nodes := []*int{new(int), new(int), new(int)}
    for i := 2; i < len(nodes); i++ {
        nodes[i] = nil // release
    }
    subslice := nodes[:2]
    fmt.Printf("FunTester: subslice = %v
", subslice)
}

Error 27: Inefficient Map Initialization

Creating a map without an initial capacity causes repeated rehashing.

package main

import (
    "fmt"
)

func main() {
    m := make(map[string]int)
    for i := 0; i < 1000; i++ {
        key := fmt.Sprintf("key%d", i)
        m[key] = i
    }
    fmt.Printf("FunTester: map size = %d
", len(m))
}

Specify the expected size when calling make.

package main

import (
    "fmt"
)

func main() {
    m := make(map[string]int, 1000) // pre‑allocate capacity
    for i := 0; i < 1000; i++ {
        key := fmt.Sprintf("key%d", i)
        m[key] = i
    }
    fmt.Printf("FunTester: map size = %d
", len(m))
}

Error 28: Map Memory Leak

Even after clearing entries, the underlying bucket memory remains allocated.

package main

import "fmt"

func main() {
    m := make(map[int][]int, 10)
    for i := 0; i < 100; i++ {
        m[i] = make([]int, 1000)
    }
    for k := range m {
        m[k] = nil // clear values
    }
    fmt.Println("FunTester: map cleared")
}

Re‑create the map to release the old memory.

package main

import "fmt"

func main() {
    m := make(map[int][]int, 10)
    // ... populate ...
    m = make(map[int][]int, 10) // new map, old memory freed
    fmt.Println("FunTester: map re‑created, old memory released")
}

Error 29: Incorrect Value Comparison

Using == on structs containing uncomparable fields is illegal; reflect.DeepEqual or custom comparators should be used.

package main

import (
    "fmt"
    "reflect"
)

type FunTester struct {
    Name string
    Age  int
}

func main() {
    a := FunTester{Name: "FunTester", Age: 30}
    b := FunTester{Name: "FunTester", Age: 30}
    if reflect.DeepEqual(a, b) {
        fmt.Println("FunTester: equal via DeepEqual")
    }
}

Prefer reflect.DeepEqual for deep struct comparison or implement a dedicated equality function.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

performanceGobest practicesfloating-pointslicesmapsinteger overflow
FunTester
Written by

FunTester

10k followers, 1k articles | completely useless

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.