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

时间:2016-06-15 12:10:36

标签: pointers go slice

我有一个结构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必须以相同的方式设置。

3 个答案:

答案 0 :(得分:13)

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)
}

答案 1 :(得分:4)

您正在尝试附加用作函数参数的map值,因此它具有本地范围,只能在函数内访问。因为它是由值引用而不是由指针地址引用,所以它的访问仅限于它的本地范围。

地图类型是引用类型,如指针或切片,因此参数p的值为nil;它没有指向初始化的地图。

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

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)
}

答案 2 :(得分:0)

很快,虽然我们可以使用slice来修改源数据,但是对于slice本身,当作为函数的参数时,它只是将副本传递给函数。 所以,你的代码就像这样

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