gpt4 book ai didi

Golang,仅附加最后一个元素

转载 作者:IT王子 更新时间:2023-10-29 02:16:30 25 4
gpt4 key购买 nike

示例代码如下:

package main

import (
"fmt"
)

type Product struct {
Id int64
Title string
AttrVals []string
}

type ProductAttrValView struct {
Product
Attr string
}

type ProductAttrVal struct {
Attr string
Product int64
Value string
}

func main() {
p := Product{Id: 1, Title: "test", AttrVals: []string{}}
var prod *Product
prodViews := []ProductAttrValView{
ProductAttrValView{ Product: p, Attr: "text1" },
ProductAttrValView{ Product: p, Attr: "text2" },
ProductAttrValView{ Product: p, Attr: "text3" },
ProductAttrValView{ Product: p, Attr: "text4" },
}

// collapse join View to Product with Attrs
for _, pview := range prodViews {
if prod == nil {
prod = &pview.Product
prod.AttrVals = make([]string, 0, len(prodViews))
}
if pview.Attr != "" {
fmt.Printf("appending '%s' to %p\n", pview.Attr, prod) // output for debug
prod.AttrVals = append(prod.AttrVals, pview.Attr)
}
}
fmt.Printf("%+v\n", prod) // output for debug

}

http://play.golang.org/p/949w5tYjcH

这里我在 ProductAttrValView 结构中有一些从 DB 返回的数据并且想要将其放入 Product 结构中并填充 Product.AttrVals

它打印:

&{Id:1 Title:test AttrVals:[text4]}

虽然我期望这样:

&{Id:1 Title:test AttrVals:[text1 text2 text3 text4]}

因此,所有文本都应附加,但出于某种原因,只有最后一个元素保留在 Attrs slice 中。

最佳答案

您在 for-range 循环中重复使用变量,并且每次迭代都会修改同一变量的值。您可以使用技巧在每次迭代中创建一个新值:

pview := pview

http://play.golang.org/p/qtJXxdtuq2

您还初始化了长度为 4 的 slice ,但是您追加 另一个值(忽略前 4 个)。您可能打算设置 slice 的容量而不是长度:

prod.AttrVals = make([]string, 0, len(prodViews))

因为 prodvalue 每次迭代都会改变,如果您专门初​​始化 prod 值,代码就会少很多困惑,而不是分配 &pview.Product

的地址
prod = &Product{AttrVals: make([]string, 0, len(prodViews))}

[时间线]

  1. 您创建了一个产品 p,其中包含一个已初始化的 []string
  2. 相同的 p 分配给我们将迭代的所有 prodViews
  3. 在循环的第一次迭代中,您将 *prod 分配给初始 p 值,然后将 AttrVals 更改为新的 []string 长度为 4。这不会改变原始 p
  4. pview.Attr 附加到 prod.AttrVals,使其长度为 5,并创建一个新的底层数组。这不会反射(reflect)在 p 的值中。
  5. 在后续迭代中,pviewprodViews 中的下一个值覆盖。这也会覆盖 prod 的值,因为它指向 pview.Product 值。这意味着 prod.AttrVals 现在与原始 p 相同。
  6. pview.Attr 附加到长度为 0 的 slice ,底层数组被替换为更多容量,所以 pview.Attr 仍然不包含在原始 p.
  7. pview 再次被下一个值覆盖,其中包含原始 p 值,将您的 AttrVals 长度设置回 0 并使用空数组.
  8. 循环继续,直到打印出最终的单个值。

关于Golang,仅附加最后一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27610039/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com