英文:
Modify values in copy of slice then append to original slice
问题
编写一个函数,用于复制一个切片并修改副本中的项目值,然后将副本附加到原始切片。代码似乎不仅修改了切片的副本,还修改了原始切片。
以下是要翻译的代码:
import "fmt"
type Item struct {
name string
number int
}
func main() {
names := []string{"a", "b"}
numbers := []int{1, 2}
items := []*Item{}
for _, name := range names {
item := &Item{name: name}
items = append(items, item)
}
for n, i := range numbers {
if n > 0 {
fmt.Println(n, "make a copy of the items")
itemCopies := make([]*Item, len(items))
copy(itemCopies, items)
fmt.Println(n, "set the numbers on the copies")
for _, item := range itemCopies {
item.number = i
}
fmt.Println(n, "append the copies to the original")
items = append(items, itemCopies...)
} else {
fmt.Println(n, "first pass set all the items to the first number")
for _, item := range items {
item.number = i
}
}
}
for n, i := range items {
fmt.Printf("%d %+v\n", n, *i)
}
}
实际看到的输出结果:
0 {name:a number:2}
1 {name:b number:2}
2 {name:a number:2}
3 {name:b number:2}
预期看到的输出结果:
0 {name:a number:1}
1 {name:b number:1}
2 {name:a number:2}
3 {name:b number:2}
你可以在Go Playground上运行这段代码。
英文:
Writing a function to copy a slice and modify the values on the items in the copy of the slice then append the copy to the original. It appears the code is not only modifying the copy of the slice but also the original slice.
import "fmt"
type Item struct {
name string
number int
}
func main() {
names := []string{"a", "b"}
numbers := []int{1, 2}
items := []*Item{}
for _, name := range names {
item := &Item{name: name}
items = append(items, item)
}
for n, i := range numbers {
if n > 0 {
fmt.Println(n, "make a copy of the items")
itemCopies := make([]*Item, len(items))
copy(itemCopies, items)
fmt.Println(n, "set the numbers on the copies")
for _, item := range itemCopies {
item.number = i
}
fmt.Println(n, "append the copies to the original")
items = append(items, itemCopies...)
} else {
fmt.Println(n, "first pass set all the items to the first number")
for _, item := range items {
item.number = i
}
}
}
for n, i := range items {
fmt.Printf("%d %+v\n", n, *i)
}
}
What I'm actually seeing
0 {name:a number:2}
1 {name:b number:2}
2 {name:a number:2}
3 {name:b number:2}
What I expected to see
0 {name:a number:1}
1 {name:b number:1}
2 {name:a number:2}
3 {name:b number:2}
答案1
得分: 1
@JimB是对的,你复制了指针。
我建议在结构体Item中定义一个copy函数
来创建一个副本。
package main
import "fmt"
type Item struct {
name string
number int
}
func (it *Item) copy() *Item {
return &Item{
name: it.name,
number: it.number,
}
}
func main() {
names := []string{"a", "b"}
numbers := []int{1, 2}
items := []*Item{}
for _, name := range names {
item := &Item{name: name}
items = append(items, item)
}
for n, i := range numbers {
if n > 0 {
fmt.Println(n, "复制items")
itemCopies := make([]*Item, len(items))
for j := 0; j < len(items); j++ {
itemCopies[j] = items[j].copy()
}
fmt.Println(n, "在副本上设置数字")
for _, item := range itemCopies {
item.number = i
}
fmt.Println(n, "将副本追加到原始items")
items = append(items, itemCopies...)
} else {
fmt.Println(n, "第一次遍历将所有items设置为第一个数字")
for _, item := range items {
item.number = i
}
}
}
for n, i := range items {
fmt.Printf("%d %+v\n", n, *i)
}
}
希望对你有帮助!
英文:
@JimB was right you copy pointers,
I suggest define a copy function belong Struct Item
to new a duplicate
package main
import "fmt"
type Item struct {
name string
number int
}
func (it *Item) copy() *Item {
return &Item{
name: it.name,
number: it.number,
}
}
func main() {
names := []string{"a", "b"}
numbers := []int{1, 2}
items := []*Item{}
for _, name := range names {
item := &Item{name: name}
items = append(items, item)
}
for n, i := range numbers {
if n > 0 {
fmt.Println(n, "make a copy of the items")
itemCopies := make([]*Item, len(items))
for j := 0; j < len(items); j++ {
itemCopies[j] = items[j].copy()
}
fmt.Println(n, "set the numbers on the copies")
for _, item := range itemCopies {
item.number = i
}
fmt.Println(n, "append the copies to the original")
items = append(items, itemCopies...)
} else {
fmt.Println(n, "first pass set all the items to the first number")
for _, item := range items {
item.number = i
}
}
}
for n, i := range items {
fmt.Printf("%d %+v\n", n, *i)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论