英文:
How to return changed values of slice from function?
问题
我是你的中文翻译助手,以下是翻译好的内容:
我刚开始学习Go语言,如果这是一个简单的问题,请原谅我。我想遍历一个帖子切片,并递增每个帖子的Views
值:
func incrementViews(posts []model.Post) []model.Post {
for _, v := range posts {
v.Views++
fmt.Println(v.Views) //Views增加了1
}
return posts
}
incrementViews(posts) //Views没有改变
打印出的值已经改变,但是当我调用incrementViews(posts)
时,返回的值没有改变。
我尝试使用*
或&
来解决这个问题,但是可能由于我来自Python背景,对于通过指针和值移动变量的概念掌握不够牢固,所以无法成功。
英文:
I'm new to go so forgive me if this is a trivial question. I want to iterate over a slice of posts and increment the value of Views
of each post:
func incrementViews(posts []model.Post) []model.Post {
for _, v := range posts {
v.Views++
fmt.Println(v.Views) //Views incremented by 1
}
return posts
}
incrementViews(posts) //Views not changed
The printed values are changed but when I call incrementViews(posts)
the returned values are unchanged.
I tried to solve this by using *
of &
but could not manage to do so perhaps because I come from Python background and have lose grasp of moving around variables by pointers and values.
答案1
得分: 1
问题中的代码正在更新局部变量 v
。要么将切片更改为 *model.Post,要么使用索引运算符更新切片中的值。前者需要对调用者进行更改。
func incrementViews(posts []*model.Post) []*model.Post {
for _, v := range posts {
v.Views++
}
return posts
}
func incrementViews(posts []model.Post) []model.Post {
for i := range posts {
posts[i].Views++
}
return posts
}
编辑:
这两种方法都可以,可以在这里查看:https://play.golang.org/p/90BNOFYaKL
英文:
The code in the question is updating the local variable v
. Either change the slice to *model.Post or update the value in the slice using the index operator. The former requires changes to the caller.
func incrementViews(posts []*model.Post) []*model.Post {
for _, v := range posts {
v.Views++
}
return posts
}
func incrementViews(posts []model.Post) []model.Post {
for i := range posts {
posts[i].Views++
}
return posts
}
EDIT:
Both approaches works, see here: https://play.golang.org/p/90BNOFYaKL
答案2
得分: 1
range
表达式返回切片元素的副本。因此,在迭代时修改切片元素时要非常小心。
对于切片或数组的range
表达式,返回的第一个参数是索引,第二个参数是该索引处元素的副本。在你的示例中,你修改的是range
返回的副本,因此在原始切片元素中没有得到修改。
你需要改变的是,使用[
索引]
来引用切片名称,这样你才能真正引用切片中的原始元素,从而可以修改原始切片元素。请参考 jeevatkm 给出的工作示例中的第二种方法。
另一种选择是使用地址的切片,在这种情况下,你可以引用range
返回的值,因为即使它是一个副本,它仍然是地址位置的副本,并且仍然指向原始元素。请参考 jeevatkm 给出的工作示例中的第一种方法。
英文:
The range
expression returns a copy of slice element. Therefore, you should be very careful when you want to modify slice element while iterating.
The range
expression on slice or an array returns first parameter as index and second parameter as copy of element at that index. In your example, you are modifying copy returned by range and hence not getting the modification in the original slice element.
What you need to change is, refer slice name with [
index]
, so that you actually refer to original element in the slice and hence can modify the original slice element. Refer to second approach in the working example given by jeevatkm.
The other option is to use slice of addresses, in this case you can refer to value returned by range, as even it is a copy, it is a copy of address location and it still points to the original element. Refer to first approach in the working example given by jeevatkm.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论