flak rss random

fixing the other go loop bug

Go 1.21 added experimental support for fixing the loop capture bug. For reasons it’s never really bothered me, but the other loop bug does bite me some times. This is the one where the loop values are values.

I want references but go doesn’t have references.

values

The problem is easy to see when you’re looking for it, and hard to see when you’re glossing over the code.

func resetScores(players []Player) {
    for _, player := range players {
        player.score = 0
    }
}

Before and after “the” loop fix, this will dutifully set the player’s score to zero. But which player? An anonymous player that only exists in the loop. The array will remain unchanged. Ugh.

hand fix

Fixing this requires slightly rewriting the loop.

func resetScores(players []Player) {
    for i := range players {
        players[i].score = 0
    }
}

This looks kinda weird I think, and it’s not my first instinct to write it this way. I really just want a way to say hi, I’m iterating over the elements of this array, give me a reference to them.

mechanical fix

So let’s add references to go.

func resetScores(players []Player) {
    for _, &player := range players {
        player.score = 0
    }
}

This can be translated by powerful state of the art tools into the go you’d have to write otherwise.

func resetScores(players []Player) {
    for  _i, _ := range players {
        player := &players[_i]
        player.score = 0
    }
}

oh well

What’s annoying is the above broken form works if the array contains pointers. A lot of my code uses pointers, so I get used to writing the first form, and then it breaks when I do something different. Or I decide to optimize the code and reduce allocations by switching from []*Player to []Player without a careful audit of the impacted loops. Alas, I probably wouldn’t think to use the reference form even if available until it’s too late.

The common mistakes wiki lists the capture bug twice, but doesn’t mention this bug.

Posted 06 Nov 2023 21:24 by tedu Updated: 06 Nov 2023 21:24
Tagged: go