Go 如何从函数返回已更改的切片值?
我是新来的,所以如果这是一个微不足道的问题,请原谅我。我想迭代一段文章,并增加每篇文章的Go 如何从函数返回已更改的切片值?,go,slice,Go,Slice,我是新来的,所以如果这是一个微不足道的问题,请原谅我。我想迭代一段文章,并增加每篇文章的Views值: func incrementViews(posts []model.Post) []model.Post { for _, v := range posts { v.Views++ fmt.Println(v.Views) //Views incremented by 1 } return
Views
值:
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
打印的值已更改,但当我调用incrementViews(posts)
时,返回的值不变
我试图通过使用
&
的*
来解决这个问题,但未能做到这一点,可能是因为我来自Python背景,对通过指针和值移动变量失去了理解 问题中的代码正在更新局部变量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
}
编辑:
这两种方法都有效,请参见此处:问题中的代码正在更新局部变量
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
}
编辑:
这两种方法都有效,请参见此处:表达式返回slice元素的副本。因此,在迭代时要修改slice元素时应该非常小心
切片或数组上的
range
表达式返回第一个参数作为索引,第二个参数作为该索引处元素的副本。在您的示例中,您正在修改由range返回的copy,因此无法在原始slice元素中获得修改
您需要更改的是,使用[
索引]
引用切片名称,以便您实际引用切片中的原始元素,从而可以修改原始切片元素。请参阅jeevatkm给出的工作示例中的
另一个选项是使用地址片,在这种情况下,您可以引用范围返回的值,因为即使它是一个副本,它也是地址位置的副本,并且仍然指向原始元素。请参阅JeevetKM给出的工作示例中的第一种方法。表达式返回slice元素的副本。因此,在迭代时要修改slice元素时应该非常小心
切片或数组上的
range
表达式返回第一个参数作为索引,第二个参数作为该索引处元素的副本。在您的示例中,您正在修改由range返回的copy,因此无法在原始slice元素中获得修改
您需要更改的是,使用[
索引]
引用切片名称,以便您实际引用切片中的原始元素,从而可以修改原始切片元素。请参阅jeevatkm给出的工作示例中的
另一个选项是使用地址片,在这种情况下,您可以引用范围返回的值,因为即使它是一个副本,它也是地址位置的副本,并且仍然指向原始元素。参考JeevetKM给出的工作示例中的第一种方法。第一种方法导致错误:
无法将posts(type[]model.Post)作为类型[]*model.Post作为incrementViews的参数使用@sahaj然后我得到两个错误:无法将posts(type[]*model.Post)作为类型[]model.Post返回参数使用和无法使用&posts(type*[]model.Post)作为type[]*model.Post-in-argument to incrementViews
@Karlom我相信请礼貌地发表您的评论。只添加了一个播放示例链接。@Karlom它是从main
func上的每一行调用的。请看一看。@Karlom我不确定您想说什么。方法incrementViews1
和incrementViews2
将slice作为输入并更改值,然后返回到main func上的调用者。我只是迭代结果,而不是存储在变量中。但结果将是相同的。您可以修改并运行它。您将看到。第一个方法导致错误:无法将posts(type[]model.Post)用作type[]*model.Post-in参数到incrementViews
@sahaj然后我得到两个错误:不能将posts(type[]*model.Post)用作type[]model.Post,而不能将&posts(type*[]model.Post)用作type[]*model.Post-in-argument to incrementViews
@Karlom我相信请礼貌地发表您的评论。只添加了一个播放示例链接。@Karlom它是从main
func上的每一行调用的。请看一看。@Karlom我不确定您想说什么。方法incrementViews1
和incrementViews2
将slice作为输入并更改值,然后返回到主func上的调用者。我只是迭代结果,而不是存储在变量中。但结果将是相同的。您可以修改并运行它。您将看到。很好的演讲。但是,这如何转化为工作代码?@shaj您刚刚在其他答案注释中复制了游乐场,即我与我的情况相关,我不会迭代incrementViews
函数来更改切片中的结构值。我不明白,你想说什么?你能把你的示例代码放到操场上,解释一下确切的疑问吗?你是想这样做的吗:。如本例所示,你可以创建一个newPosts
slice保留更改的元素,然后返回。是的,这是我们想要实现的,但如果可能的话,不需要在函数中创建新的片段。很好的演讲。但是,这如何转化为工作代码呢?@shaj你只是在其他答案注释中复制了游乐场,这与我的情况无关,我不会重复增量视图代码>函数以获取切片内的结构值。无法理解,您想说什么?请您将示例代码放在操场上,并解释确切的疑问。您是否打算这样做:。如本例所示,您可以创建一个newPosts
切片来保存更改的元素