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

Pra*_*eek 16 pointers go slice

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

type ProductInfo struct {
    TopAttributes []map[string]interface{}
}
Run Code Online (Sandbox Code Playgroud)

我想设置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)
}
Run Code Online (Sandbox Code Playgroud)

但这似乎不起作用.

但是,当我将方法定义为:时,还有另一种方法可以正常工作:

   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)
}
Run Code Online (Sandbox Code Playgroud)

我想找出它为什么不起作用.我的代码中没有错误,但数据是空的.我试图这样做使它成为一个泛型函数,因为我有另一个BottomAttributes必须以相同的方式设置.

Kev*_*ger 18

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)
}
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了上面的方法,但错过了 *p =append(*p, val) 部分。谢谢,现在可以使用了。 (3认同)
  • 我有另一个问题 - 所有切片和地图都作为参考传递。因此,当我传递 TopAttributes 的引用(这是一个切片)并将值设置为 p =append(p, val) 时,它不应该工作吗?这也在某种程度上更新了参考文献。 (3认同)
  • 您正在更新参考。但只有 setAttribute 看到的引用。当您使用指向该“引用”的指针时,您正在更新 setAttributeData 具有的变量。在 C 术语中,它是一个指向指针的指针。 (2认同)

End*_*imo 6

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

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)
}
Run Code Online (Sandbox Code Playgroud)