Golang Go语言中 append struct 问题,请诸位大神留步一观

Golang Go语言中 append struct 问题,请诸位大神留步一观

小弟今天开发项目,发现一个奇怪问题 首先小弟的信息是从数据库中取出来的,取出来预备组成[]struct 返回给前端,进行任务展示,这是前提 数据库中有任务三条, 任务 1:

{[{false 1KB-20KB}] [] []}} b5a33d9d-6512-11ea-8001-000000000000 {2 0 }

任务 2:

{[{true 1GB-1TB}] [] []}} fee23a86-6506-11ea-8001-000000000000 {2 0 }}

任务 3:

{[{false 1KB-2KB}] [] []}} 9b995076-6514-11ea-8002-000000000000 {2 0 }

我利用了 append,组合成一个[]struct,可是输出之后发现

[{{[] [{false 1KB-2KB}] [] []}} 9b995076-6514-11ea-8002-000000000000 {2 0 }},
 {{[]{false 1KB-2KB}] [] []}} fee23a86-6506-11ea-8001-000000000000 {2 0 }}, 
  {{[{false 1KB-2KB}] [] []}} b5a33d9d-6512-11ea-8001-000000000000 {2 0 }}]

所有的 false 都被固定成 1kb-2kb 了,小弟写过 python,怀疑是 deepcopy 或者是 copy 的问题,但是 golang 这里实在不熟,请各位大神给小弟一点点灵感吧,谢谢!


更多关于Golang Go语言中 append struct 问题,请诸位大神留步一观的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

看不懂,是我的话就提前定义好 struct,取出来以后全还原到 struct 对象,再处理

更多关于Golang Go语言中 append struct 问题,请诸位大神留步一观的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


全部都 unmarshal 到同一块内存了,你应该每轮迭代定义个新 sync

对,您的点拨很到位,谢谢谢谢!感恩

好像知乎上看到你的问题,回答了你,怀疑是 for-range 用了指针,参考: https://mp.weixin.qq.com/s/klJBAi5LvdJOGvma2Ir0OA

for-range 的经典坑。

#2
又看了一下,还有点问题
如果你那个infimanage.Sync是个 interface 并且实际类型是个 pointer 的话才会出现我#2 说的问题,不过看你最后生成的数据里只有{false 1KB-2KB}相同,后面的 uuid 是不同的,那么就排除我#2 说的情况。猜测是你后两次迭代的 JSON 数据中{false 1KB-2KB}字段有误(比如字段名出错),导致只 unmarshal 了后面的正常数据到你复用的 sync 里,然后把 sync 的拷贝 append

而且你粘贴的输出明显有问题:
{[] [{false 1KB-2KB}] [] []}}
{[]{false 1KB-2KB}] [] []}}
{[{false 1KB-2KB}] [] []}}
建议按上面几点自己排查一下

把第一行 var sync infimanage.Sync 挪到 for 循环里面。

在Golang中,使用append函数向切片中添加元素是常见的操作。当涉及到向切片中添加结构体(struct)时,需要注意几个关键点:

  1. 直接追加:你可以直接将结构体实例追加到切片中。例如,如果你有一个Person结构体切片people,你可以通过people = append(people, personInstance)来添加一个新的Person实例。

  2. 内存分配append操作可能会导致底层数组的重新分配和复制,特别是当切片容量不足时。因此,如果结构体较大或切片很长,频繁追加可能会影响性能。在这种情况下,可以考虑预先分配足够的容量。

  3. 值复制:在Go中,结构体是值类型。当你将结构体追加到切片中时,实际上是复制了该结构体的值。这意味着切片中的结构体和原始结构体是两个独立的实例,修改切片中的结构体不会影响原始结构体。

  4. 并发安全:如果多个协程同时向同一个结构体切片追加元素,需要确保操作是并发安全的。可以使用互斥锁(sync.Mutex)来保护切片。

  5. 示例代码

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{}
    p := Person{Name: "Alice", Age: 30}
    people = append(people, p)
    fmt.Println(people)
}

上述代码演示了如何向一个Person结构体切片中添加元素。希望这些信息能帮到你!

回到顶部