6

Golang Gotcha: Modifying an array of structs

 1 year ago
source link: https://blog.davidvassallo.me/2022/05/11/golang-gotcha-modifying-an-array-of-structs/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Golang Gotcha: Modifying an array of structs

Scenario

Using Golang, we initialize an array of structs, within which we’d like to change a field by iterating over the initialized array. This would be necessary (for example) to initialize certain struct fields.

An initial pass at the code may look something like this:

// play with this code here: https://go.dev/play/p/VH0duYxZVZn
package main
import "fmt"
type DemoType struct {
Test string
}
var DemoTypeArray = []DemoType{
DemoType{
Test: "asdfg",
},
DemoType{
Test: "qwerty",
},
}
func main() {
fmt.Printf("==================================\nCycling and 'modifying':\n==================================\n")
for _, demoTypeInstance := range DemoTypeArray {
fmt.Println(demoTypeInstance.Test)
demoTypeInstance.Test = "modified"
}
fmt.Printf("==================================\nAfter 'modification':\n==================================\n")
for _, demoTypeInstance := range DemoTypeArray {
fmt.Println(demoTypeInstance.Test)
}
}

The output of the above code playground ( https://go.dev/play/p/VH0duYxZVZn ) would show:

==================================
Cycling and 'modifying':
==================================
asdfg
qwerty
==================================
After 'modification':
==================================
asdfg
qwerty

The below line should modify the “Test” field of each struct to “modified”:

demoTypeInstance.Test = "modified"

But clearly that didn’t happen. What gives? In more complex programs this could end up leading to a panic due to a nil reference. A careful inspection of the code reveals the culprit is the for loop. The “range” command outputs two variables… the index of a given item in an array and a copy of the item in the array.

That last comment is key. In our for loop, we are actually modifying the copy of the data, not the data item in the array itself. A solution is to use the index to modify the actual data item, as follows:

// play with this code here: https://go.dev/play/p/NA089ZOURdr
package main
import "fmt"
type DemoType struct {
Test string
}
var DemoTypeArray = []DemoType{
DemoType{
Test: "asdfg",
},
DemoType{
Test: "qwerty",
},
}
func main() {
fmt.Printf("==================================\nCycling and 'modifying':\n==================================\n")
for idx, demoTypeInstance := range DemoTypeArray {
fmt.Println(demoTypeInstance.Test)
DemoTypeArray[idx].Test = "modified"
}
fmt.Printf("==================================\nAfter 'modification':\n==================================\n")
for _, demoTypeInstance := range DemoTypeArray {
fmt.Println(demoTypeInstance.Test)
}
}

The output of the above code playground ( https://go.dev/play/p/NA089ZOURdr ) would show:

==================================
Cycling and 'modifying':
==================================
asdfg
qwerty
==================================
After 'modification':
==================================
modified
modified

Success! Note the following in the modified code:

  • In our for loop, we no longer ignore the index argument, we now store it in “idx”
  • To modify the item stored in the array we user the idx variable to directly reference the item within the array
Loading...

Related

Posted in development, golangTagged development, golang

Post navigation

Search for:

Like This Blog? Buy Me A Coffee!

buymeacoffee.jpeg?w=1200

Email Subscription

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 615 other followers

Email Address:

cybersift_banner

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK