Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modify array of interface{} golang

Tags:

go

This type assertion, def-referencing has been driving me crazy. So I have a nested structure of Key string / Value interface{} pairs. Stored in the Value is an []interface which I want to modify each of the values. Below is an example of creating an array of Bar and passing it into the ModifyAndPrint function which should modify the top level structure. The problem that I come accross is as written it doesn't actually modify the contents of z, and I can't do a q := z.([]interface{})[i].(Bar) or & thereof.

Is there a way to do this? If so, what combination did I miss?

package main

import "fmt"

type Bar struct {
   Name string
   Value int
}

func ModifyAndPrint(z interface{}){
    fmt.Printf("z before: %v\n", z)
    for i, _ := range(z.([]interface{})) {      
        q := z.([]interface{})[i]
        b := (q).(Bar)
        b.Value = 42
        fmt.Printf("Changed to: %v\n", b)
    }
    fmt.Printf("z after: %v\n", z)
}

func main() {       
    bars := make([]interface{}, 2)
    bars[0] = Bar{"a",1}
    bars[1] = Bar{"b",2}

    ModifyAndPrint(bars)    
}

https://play.golang.org/p/vh4QXS51tq

like image 424
FuriousGeorge Avatar asked May 26 '26 08:05

FuriousGeorge


1 Answers

The program is modifying a copy of the value in the interface{}. One way to achieve your goal is to assign the modified value back to the slice:

for i, _ := range(z.([]interface{})) {      
    q := z.([]interface{})[i]
    b := (q).(Bar)
    b.Value = 42
    z.([]interface{})[i] = b
    fmt.Printf("Changed to: %v\n", b)
}

playground example


Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!