You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang遍历struct切片生成指针切片结果异常如何修复?

问题根因

这是Go for range循环的经典特性:range迭代过程中,用于接收元素值的迭代变量ele只会被初始化一次,后续所有遍历操作只会将切片对应位置的元素值拷贝到ele的固定内存地址中。因此你循环中每次取&ele拿到的都是同一个内存地址,遍历结束后该地址存储的是切片最后一个元素的值,才会出现所有返回指针都指向最后一本drama类图书的问题。

修复方案

你可以根据业务场景选择以下两种修复方式:

  • 方案1:循环内创建局部变量拷贝值后取指针
    每次匹配到符合条件的元素时,先将ele赋值给当前循环块内的局部临时变量,再取该临时变量的指针加入结果集。这个方案返回的指针指向新创建的副本,修改返回值不会影响原books切片的内容。
func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for _, ele := range books {
        if ele.Genre == genre {
            // 创建循环块内的局部临时变量,每次循环都会分配新的内存地址
            temp := ele
            response = append(response, &temp)
        }
    }
    return response
}
  • 方案2:直接取原切片对应索引元素的指针
    遍历的时候通过索引访问原切片的元素,直接取原元素的地址,不需要额外值拷贝。这个方案返回的指针指向原books切片的元素,修改返回值会同步修改原切片内容,适合需要同步修改原数据的场景。
func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    // 遍历使用索引,不用值迭代变量
    for i := range books {
        if books[i].Genre == genre {
            // 直接取原切片元素的指针
            response = append(response, &books[i])
        }
    }
    return response
}

内容的提问来源于stack exchange,提问作者User_Targaryen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 01:51:01