gpt4 book ai didi

golang 从指针类型 slice 复制指针值

转载 作者:数据小太阳 更新时间:2023-10-29 03:22:29 25 4
gpt4 key购买 nike

type Order struct {
*Res
Status int
}

type Res struct {
ResID int64
OtaBookID string
StayDetail []*ResElement
TotalCharge float64
CustFName string
CustLName string
CreateTime time.Time
}

type ResElement struct {
Res *Res
OtaEleID string
OtaRoomID string
RoomID int
Arrival time.Time
Depart time.Time
Charge float64
CreateTime time.Time
}

我有一个名为 orderList 的 slice 来记录订单。现在我有第一个 OtaBookID 是“A123”的订单,我想复制这个订单并将其 OtaBookID 更改为“B123”。 ResElement 类型有一些其他详细信息来记录此订单,我隐藏它们,因为它不会影响我的问题。我可以成功更改 Res.OtaBookID 但我不知道如何更改 Res.StayDetail[0].Res.OtaBookID

func main() {
var orderList []*Order

res := new(Res)
res.OtaBookID = "A123"

resElt := new(ResElement)
resElt.Res = res
res.StayDetail = append(res.StayDetail, resElt)

order := new(Order)
order.Res = res

orderList = append(orderList, order)

originalOrder := new(Order)
originalOrder.Res = new(Res)
*originalOrder.Res = *order.Res
//originalOrder.Res.StayDetail[0].Res.OtaBookID = "B123" //this will make all become "B123"

originalOrder.Res.OtaBookID = "B123"

orderList = append(orderList, originalOrder)

fmt.Println(orderList[0].Res.OtaBookID) //A123
fmt.Println(orderList[1].Res.OtaBookID) //B123
fmt.Println(orderList[0].Res.StayDetail[0].Res.OtaBookID) //A123
fmt.Println(orderList[1].Res.StayDetail[0].Res.OtaBookID) //A123, i want this become B123
}

我要的结果是orderList[0].Res.OtaBookID 和orderList[0].Res.StayDetail[0].Res.OtaBookID 是"A123"其他是"B123"

ps:因为我在接手别人的作品。所以三型已经固定,无法调整。我想知道在这种情况下是否有什么方法可以达到我的目标

最佳答案

根据您的示例和说明,我们可以专注于 main 来实现您的目标:

type Order struct {
*Res
Status int
}

type Res struct {
ResID int64
OtaBookID string
StayDetail []*ResElement
TotalCharge float64
CustFName string
CustLName string
CreateTime time.Time
}

type ResElement struct {
Res *Res
OtaEleID string
OtaRoomID string
RoomID int
Arrival time.Time
Depart time.Time
Charge float64
CreateTime time.Time
}

func main() {
var orderList []*Order

res := new(Res)
res.OtaBookID = "A123"

resElt := new(ResElement)
resElt.Res = res
res.StayDetail = append(res.StayDetail, resElt)

order := new(Order)
order.Res = res

orderList = append(orderList, order)

originalOrder := new(Order)
originalOrder.Res = new(Res)

// The following statement will copy the values in the memory space of order to the memory
// space of originalOrder, but take note that a pointer contains a memory address. Thus,
// following this statement originalOrder.Res.StayDetail will point to the same address
// as order.Res.StayDetail as slices are pointers...
*originalOrder.Res = *order.Res

// We now have to manually copy the slice to ensure it is different from the one in order.
// We must create a new slice to avoid overwriting the source.
originalOrder.Res.StayDetail := make([]*ResElement, len(order.Res.StayDetail))

// Further, this slice contains pointers so we must copy these as well to ensure they do not
// point to the ResElements of order.
for i, v := range order.Res.StayDetail {
re := new(ResElement)

// copy the values of the memory in v to the values in the memory of re
*re = *v

// set re.Res to point to originalOrder.Res as it currently point to order.Res
re.Res = originalOrder.Res

// Now we must place re in the slice of originalOrder as it currently points to an
// empty array of the correct size. Thus, we will not use append (which will grow
// the size), we will just set the index to the correct value. Thus:
originalOrder.StayDetail[i] = re
}
// The pointers and structures have now been properly set up, thus the following are equivalent:
// originalOrder.OtaBookID = "B123" - Res via embedding
// originalOrder.Res.OtaBookID = "B123" - Res directly
// originalOrder.Res.StayDetail[0].Res.OtaBookID = "B123" - Res via ResElement pointer Res
// They all point to the exact same memory space

originalOrder.Res.OtaBookID = "B123"

orderList = append(orderList, originalOrder)

fmt.Println(orderList[0].Res.OtaBookID) //A123
fmt.Println(orderList[1].Res.OtaBookID) //B123
fmt.Println(orderList[0].Res.StayDetail[0].Res.OtaBookID) //A123
fmt.Println(orderList[1].Res.StayDetail[0].Res.OtaBookID) //B123
}

永远记住,指针只是一个内存地址。如果地址值为 0xffab67e1,则指针的副本也将包含与 0xffab67e1 相同的值,并有效地指向同一事物。因此,您必须故意在新地址分配新的内存空间并复制内部值。必须对包含指针的任何结构执行此操作。我们称之为深度复制或克隆。

关于golang 从指针类型 slice 复制指针值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51356836/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com