Pointers Go指针-通过指针将值附加到切片

Pointers Go指针-通过指针将值附加到切片,pointers,go,slice,Pointers,Go,Slice,我有一个struct ProductData及其实例p,它有一个slice属性: type ProductInfo struct { TopAttributes []map[string]interface{} } 我想如下设置TopAttributes func (p *ProductInfo) setAttributeData() { key := "key" value := "value" setAttribute(p.TopAttributes, ke

我有一个struct ProductData及其实例p,它有一个slice属性:

type ProductInfo struct {
    TopAttributes []map[string]interface{}
}
我想如下设置TopAttributes

func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    setAttribute(p.TopAttributes, key, value)
}

func setAttribute(p []map[string]interface{}, key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    p = append(p, val)
}
但这似乎不起作用。 但是,当我将一个方法定义为:

   func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    p.setAttribute(key, value)
}

func (p *ProductInfo) setAttribute(key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    p.TopAttributes = append(p.TopAttributes, val)
}
我想知道为什么它不起作用。我的代码中没有错误,但是数据是空的。
我试图这样做,使它成为一个通用函数,因为我有另一个BottomAttributes,必须以相同的方式设置

append
返回对附加到切片的引用。这是因为如果需要调整大小,它可以指向内存中的新位置

在第一个示例中,您正在更新传递给
setAttribute
函数的变量,但仅此而已。当该函数退出时,唯一的引用将丢失

它在第二个示例中起作用,因为该变量存在于结构中,因此被更新

您可以使用指针修复第一个版本:

func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    setAttribute(&p.TopAttributes, key, value)
}

func setAttribute(p *[]map[string]interface{}, key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    *p = append(*p, val)
}

您试图附加一个
映射
值,该值用作函数参数,因此它有一个局部作用域,只能在函数中访问。因为它是由值而不是指针地址引用的,所以它的访问仅限于其本地范围

映射类型是引用类型,如指针或切片,因此参数
p
的值为零;它不指向已初始化的映射

要将其指向地图,您必须通过其指针访问:

func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    setAttribute(p.TopAttributes, key, value)
}

func setAttribute(p *[]map[string]interface{}, key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    *p = append(*p, val)
}

简而言之,虽然我们可以使用slice来修改源数据,但对于slice本身,当它作为函数的参数时,它只是将一个副本传递给函数。 你的代码是这样的

func test(i int) {
    i = i + 1
}
var a int = 3
test(a)

请给出一个基于你给我们的代码,这甚至不应该编译。您正在引用attrData,是指attrCode吗?我已经给出了所需的代码。我尝试了上述操作,但没有找到*p=append(*p,val)部分。谢谢,它正在工作。我还有一个问题-所有的切片和地图都作为参考传递。因此,当我传递TopAttributes的引用(这是一个切片)并将值设置为p=append(p,val)时,它不应该工作吗。这也是以某种方式更新引用。您正在更新引用。但只有setAttribute看到的引用。当您使用指向该“引用”的指针时,您正在更新setAttributeData拥有的变量。在C语言中,它是指向指针的指针。