KERNEL PANIC

FATAL_ERROR: RED_BULL_RESERVOIR_EMPTY

A problem has been detected and systems have been shut down to prevent damage to your sanity.


*** STOP: 0x000000GO (0x000000RU, 0x000000ST, 0x000000SRE, 0x000000AI)


Rebooting in 5 seconds...

Originally published on an external platform.

I’m writing this blog in the hope that the silly mistakes I made—and learned from—while coding in Go can help others avoid them. I learned the hard way how to fix these issues, and the process encouraged me to dive deeper into the language.

My goal is to keep this short and to the point. Most of these are simple misunderstandings, but every lesson counts!

1. Array vs. Slice

In Go, arrays are values with a fixed length. They are not pointers or references. When you pass an array to a function or assign it to another variable, you are creating a full copy of the original array.

Use Slices instead: Slices are reference types. They can be passed to functions efficiently, and you can use the built-in append function to modify them.

Array behavior (Copy by value):

func ChangeArray(arr [5]int) {
    arr[0] = 21
}

func main() {
    v := [5]int{1, 2, 3, 4, 5}
    ChangeArray(v) 
    fmt.Println(v) // Output: [1 2 3 4 5]
}

Slice behavior (Reference type):

func ChangeSlice(arr []int) {
    arr[0] = 21
}

func main() {
    v := []int{1, 2, 3, 4, 5}
    ChangeSlice(v) 
    fmt.Println(v) // Output: [21 2 3 4 5]
}

2. Strings are Immutable

In Go, strings are immutable byte slices. You cannot change a string’s data directly. To modify a string, you should convert it to a []byte or []rune slice. I recommend []rune to properly support UTF-8 characters.

str := "modifyString"
// str[6] = "s" // Error: Cannot assign to str[6]

runeStore := []rune(str)
runeStore[6] = 's'
fmt.Println(string(runeStore)) // Output: modifystring

3. Multiple Returns and Assignments

You must use multiple assignments when a function returns more than one value. Use the blank identifier (_) if you want to ignore specific return values.

func returnValues() (int, int) {
    return 1, 2
}

// value := returnValues() // Error: assignment mismatch
_, value := returnValues()   // Correct way to ignore the first value

4. Operator Precedence

In Go, the multiplication, division, and remainder operators have the same precedence and are evaluated from left to right. Use parentheses () to force a specific order.

func main() {
    n := 43210 
    fmt.Println(n/60*60, "hours and", n%60*60, "seconds")     // Incorrect
    fmt.Println(n/(60*60), "hours and", n%(60*60), "seconds") // Correct
}

5. Nil is Not Always Nil

An interface value is equal to nil only if both its value and its dynamic type are nil. This can be confusing when comparing an interface to a concrete pointer that is nil.

func main() {
    var a *int = nil
    var b interface{} = nil
    var c interface{} = a
    
    fmt.Println(a == b) // false
    fmt.Println(a == c) // true
}

6. Empty JSON Output

If your json.Marshal call returns an empty object {}, it’s likely because your struct fields are not exported (they must start with a capital letter).

type Food struct {
    name string // Unexported, will be ignored by JSON
}

type FavFood struct {
    Name string // Exported, will work
}

7. Changing Values in a range Loop

A range loop creates a copy of the elements. Modifying the loop variable does not change the original slice. To modify the slice, use the index.

sliceOfInts := []int{1, 2, 3, 4, 5}
for _, v := range sliceOfInts {
    v += 1 // Only modifies the local copy 'v'
}

for i := range sliceOfInts {
    sliceOfInts[i] += 2 // Modifies the original slice via index
}

8. Regular Expression Matching

The regexp.MatchString function performs substring matching by default. To match the entire string, you must use the start (^) and end ($) anchors.

func main() {
    pattern := `[0-9]*`
    matched, _ := regexp.MatchString(pattern, "12three45")
    fmt.Println(matched) // true (matches the "12" or "45")

    strictPattern := `^[0-9]*$`
    matched, _ = regexp.MatchString(strictPattern, "12three45")
    fmt.Println(matched) // false
}

These are some of the silly but interesting things I learned. I’ll keep them coming as I discover more!

Go Gopher

Hope you enjoyed these tips!

Happy Coding!!

36.5°C
CORE TEMPERATURE

KERNEL PANIC

Critical system failure. All Gophers have escaped.

Rebooting universe in 5...

Error: PEBKAC_EXCEPTION
Address: 0xDEADBEEF