指针切片到一个结构体的问题

huangapple go评论71阅读模式
英文:

Slice of pointers to a struct golang issue

问题

我在我的存储库层有一个函数,应该返回一个指针的切片,但是代码不能正常工作。

var books []model.Book

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for _, ele := range books {
        if ele.Genre == genre {
            response = append(response, &ele)
        }
    }
    return response
}

我试图遍历书籍列表,并根据书籍的genre与输入的genre匹配来返回一个指针的切片。

我进行了调试,并发现问题是由于ele被更新而导致response中现有指针混乱。

问题在于,如果按照genre的顺序插入了3本书,分别为comedythrillerdrama,并且如果以comedythriller作为genre调用GetBooksByGenre,那么输出将是drama,因为这是我遍历列表时的最后一个条目。

我该如何解决这个问题?

英文:

I have a function in my repository layer which should return a slice of pointers, but the code does not work properly.

var books []model.Book

func GetBooksByGenre(genre string) []*model.Book {
	var response []*model.Book
	for _, ele := range books {
		if ele.Genre == genre {
			response = append(response, &ele)
		}
	}
	return response
}

I am trying to iterate over the list of books and finally return a slice of pointers based on the genre of the book matching the input genre.

I debugged and found that the issue is there due to ele getting updated and messing up the existing pointers in the var response

The problem is that if there are 3 books inserted in the order of genre as comedy, thriller and drama and if GetBooksByGenre is called with genre as comedy or thriller, then the output is coming as drama as that is the last entry when I iterate the list.

How can I fix this issue?

答案1

得分: 5

该程序使用变量ele的地址填充切片。其中一种修复方法是使用切片元素的地址:

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for i, ele := range books {
        if ele.Genre == genre {
            response = append(response, &books[i])
        }
    }
    return response
}

另一种修复方法是将books更改为[]*model.Book而不是[]model.Book。在进行此更改的情况下,请使用以下代码:

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for _, ele := range books {
        if ele.Genre == genre {
            response = append(response, ele)
        }
    }
    return response
}

还有一种修复方法是为每次迭代创建一个新变量,并使用该变量的地址:

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for _, ele := range books {
        if ele.Genre == genre {
            ele := ele // <-- 新变量
            response = append(response, &ele)
        }
    }
    return response
}

你可能想要使用这里介绍的前两个选项中的一个。

英文:

The program fills the slice with the address of variable ele. One fix is to use the address of the slice element:

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for i, ele := range books {
        if ele.Genre == genre {
            response = append(response, &amp;books[i])
        }
    }
    return response
}

Another fix is to change books to be a []*model.Book instead of a []model.Book. Use this code with that change:

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for _, ele := range books {
        if ele.Genre == genre {
            response = append(response, ele)
        }
    }
    return response
}

Yet another fix is to create a new variable for each iteration and use the address of that variable:

func GetBooksByGenre(genre string) []*model.Book {
    var response []*model.Book
    for _, ele := range books {
        if ele.Genre == genre {
            ele := ele // &lt;-- new variable
            response = append(response, &amp;ele)
        }
    }
    return response
}

You probably want one of the first two options presented here.

huangapple
  • 本文由 发表于 2021年7月5日 00:56:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/68246995.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定