猿问

指向具有略微不同值的结构的指针的重复切片

给定两个嵌套类型


type Inner struct {

  InnerVal int

}


type Outer struct {

  InnerStruct *Inner

  OuterVal int

}

我需要复制一个指针切片Outer


originalSlice := []*Outer{<plenty_of_items>}

本身,但在重复项中更新了字段值,包括Outer.InnerStruct.InnerVal.


为此,我创建了一个类型和长度originalSlice与originalSlice


duplicateSlice := make([]*Outer, len(originalSlice))


for _, originalItem := range originalSlice {

  duplicateSlice = append(duplicateSlice, &Outer{

    InnerStruct: &Inner{

      InnerVal: originalItem.InnerStruct.InnerVal + 1

    },

    OuterVal: originalItem.OuterVal + 1,

  })

}


originalSlice = append(originalSlice, duplicateSlice...)

虽然这很冗长,可以跟随周围的指针,或者我认为,当在 as 之后立即传递给函数nowDoubledSlice并通过循环访问时


someOtherSlice := make([]*types.Inner, len(nowDoubledSlice))


for i, doubledItem := range nowDoubledSlice {

  someOtherSlice[i] = doubledItem.InnerStruct

}

我得到一个


运行时错误:无效的内存地址或 nil 指针取消引用


这是为什么?是否有更优雅或惯用的方法来复制指向结构的指针切片,同时更改重复项的字段?


慕少森
浏览 149回答 1
1回答

小怪兽爱吃肉

这与您的指针创建无关,这是您的切片分配。这一行:duplicateSlice := make([]*Outer, len(originalSlice))创建一个新的长度切片len(originalSlice),填充零值元素。您可能想要的是:duplicateSlice := make([]*Outer, 0, len(originalSlice))创建一个长度0但容量为的切片len(originalSlice)。这很好用,你可以在这里看到。或者,您可以保留make([]*Outer, len(originalSlice))并使用索引而不是append在循环中:for i, originalItem := range originalSlice {&nbsp; &nbsp; duplicateSlice[i] =&Outer{&nbsp; &nbsp; &nbsp; &nbsp; InnerStruct: &Inner{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InnerVal: originalItem.InnerStruct.InnerVal + 1,&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; OuterVal: originalItem.OuterVal + 1,&nbsp; &nbsp; }}正如您在此处看到的那样,它也同样有效。
随时随地看视频慕课网APP

相关分类

Go
我要回答