Go语言结构体栈元素被覆盖问题及结构体深拷贝实现方案
在Go中实现栈元素的深拷贝解决方法
你的问题根源在于Go语言中map是引用类型,当你将StateContextStackCompartment(或其指针)推入栈时,结构体中的StateVars、StateArgs等map字段只是复制了引用,指向同一个底层哈希表。因此修改原实例的map值时,栈中元素的map也会同步变化。
要实现真正的深拷贝,需要为StateContextStackCompartment编写一个深拷贝方法,手动复制所有map及其他引用类型字段。
步骤1:为StateContextStackCompartment实现DeepCopy方法
func (c *StateContextStackCompartment) DeepCopy() *StateContextStackCompartment { // 创建新的结构体实例,复制基础值类型字段 copyComp := &StateContextStackCompartment{ State: c.State, } // 深拷贝StateArgs copyComp.StateArgs = make(map[string]interface{}, len(c.StateArgs)) for k, v := range c.StateArgs { // 若map值为引用类型(如嵌套map、切片),需递归拷贝,当前示例为基础类型直接赋值 copyComp.StateArgs[k] = v } // 深拷贝StateVars copyComp.StateVars = make(map[string]interface{}, len(c.StateVars)) for k, v := range c.StateVars { copyComp.StateVars[k] = v } // 深拷贝EnterArgs copyComp.EnterArgs = make(map[string]interface{}, len(c.EnterArgs)) for k, v := range c.EnterArgs { copyComp.EnterArgs[k] = v } // 深拷贝ExitArgs copyComp.ExitArgs = make(map[string]interface{}, len(c.ExitArgs)) for k, v := range c.ExitArgs { copyComp.ExitArgs[k] = v } // 处理_forwardEvent_指针:若需深拷贝FrameEvent实例,复制其值并生成新指针 if c._forwardEvent_ != nil { copyEvent := *c._forwardEvent_ copyComp._forwardEvent_ = ©Event } return copyComp }
步骤2:入栈前使用深拷贝后的实例
将原指针推入栈的操作,替换为推入深拷贝后的新实例:
// 原入栈操作(会导致共享引用): // stack.stack = append(stack.stack, *m._compartment_) // 修改为深拷贝后入栈: copied := m._compartment_.DeepCopy() stack.stack = append(stack.stack, *copied)
注意事项
- 如果你的map中存储的是嵌套引用类型(如
map[string]map[string]interface{}、切片、自定义结构体指针等),需要在DeepCopy方法中递归处理这些类型,确保所有层级都完成深拷贝。 - 若
framelang.FrameEvent包含引用类型字段,也需要为其实现对应的深拷贝逻辑,避免共享底层数据。
内容的提问来源于stack exchange,提问作者Deepak Sharma
相关产品推荐
相关产品推荐

