Understanding Element Referencing in Range Loops: Avoid Common Gotchas in Go

Hey, fellow Gophers! :hamster:

I recently wrote an article diving into a subtle but important aspect of Go’s range loops: element referencing. If you’ve ever found yourself scratching your head over unexpected behaviour when working with slices, maps, or other collections in a range loop, this is for you.

What’s Covered in the Article

  • How range handles elements and pointers internally.
  • Common pitfalls developers encounter, like unintentional modifications or wrong outputs.
  • Tips and best practices to avoid these issues while writing cleaner, bug-free Go code.

Here’s a quick example to illustrate:

func getAvatarUrl(characterId int) string{
	// Simulate getting URL
	return fmt.Sprintf("https://base-url/%d", characterId)
}
type CharacterInfo struct {
    id          int
    characterName string
    avatarUrl   string
}
charactersOfGOT := []CharacterInfo{
    {id: 1, characterName: "Jon Snow"},
    {id: 2, characterName: "Daenerys Targaryen"},
    {id: 3, characterName: "Arya Stark"},
    {id: 4, characterName: "Tyrion Lannister"},
}

for _, charInfo := range charactersOfGOT {
    charInfo.avatarUrl = getAvatarUrl(charInfo.id)
}

for _, charInfo := range charactersOfGOT {
    fmt.Printf("Id: %d Name: %s, avatar: %s\n", charInfo.id, charInfo.characterName, charInfo.avatarUrl)
}

If this code doesn’t behave the way you’d expect, you’re not alone! In my article, I explain why this happens and how to write robust code that avoids such traps.

Read the Full Article

:point_right: Know How Elements Are Referenced in Range Loops to Avoid Common Pitfalls in Go

Let’s Discuss

Have you encountered similar challenges with range loops? What strategies have you used to avoid these gotchas? I’d love to hear your thoughts, tips, and experiences here! Let’s collaborate and help each other level up in Go programming. :raised_hands:

2 Likes

Are there any proposals for a syntax to use reference instead of copy in a for loop?
The syntax could look like this:

for _, *charInfo := range charactersOfGOT {
    charInfo.avatarUrl = getAvatarUrl(charInfo.id)
}

Golang playground link to this code: The Go Playground

1 Like