修改 Golang 中的 interface{} 数组。

huangapple go评论80阅读模式
英文:

Modify array of interface{} golang

问题

这个类型断言和解引用让我很困惑。我有一个嵌套的Key string / Value interface{}对的结构。存储在Value中的是一个[]interface{},我想修改每个值。下面是一个创建Bar数组并将其传递给ModifyAndPrint函数的示例,该函数应该修改顶层结构。我遇到的问题是,按照现在的写法,它实际上不会修改z的内容,而且我不能使用q := z.([]interface{})[i].(Bar)&

有没有办法做到这一点?如果有,我错过了哪个组合?

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

英文:

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

答案1

得分: 7

程序正在修改interface{}中的值的副本。实现你的目标的一种方法是将修改后的值重新赋给切片:

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示例

英文:

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

huangapple
  • 本文由 发表于 2015年1月21日 04:52:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/28054913.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定