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
相关产品推荐
相关产品推荐

