克隆包含对旧结构的引用的结构体函数字段

问题描述 投票:0回答:1

我有一个包含函数字段的结构,并且该字段包含对结构本身的引用。我想在这个结构上实现一个 Clone 方法来进行深度复制,但是函数字段始终保留对旧结构的引用,因此我无法进行正确的深度复制。

这是我的问题的一个非常简化的版本:

package main

import "fmt"

type MyStruct struct {
    name  string
    printName func()
}

func NewMyStruct() *MyStruct {
    return &MyStruct{}
}

func (s *MyStruct) SetName(n string) {
    s.name = n
}

func (s *MyStruct) SetPrint(fn func()) {
    s.printName = fn
}

func (s *MyStruct) Clone() *MyStruct {
    newS := &MyStruct{
        name:  s.name,
        printName: s.printName,
    }
    return newS
}

func main() {
    s := NewMyStruct()
    s.SetPrint(func() {
        fmt.Println(s.name)
    })

    s.printName() // prints "" as expected

    s.SetName("brother")
    s.printName() // prints "brother" as expected

    sClone := s.Clone()
    sClone.printName() // prints "brother" as expected

    sClone.SetName("sister")
    sClone.printName() // prints "brother" which I don't want it to
}

主要问题是打印函数是在运行时设置的,因此我无法重写 Clone 方法中的闭包。有没有办法在这个结构上实现适当的深度克隆?

我想到的一个解决方案是让函数采用 MyStruct 作为参数,以便它始终本地化,但这会破坏界面,因此我正在寻找任何其他解决方案。

更新:更新了代码以更清楚地显示约束。

go struct clone
1个回答
0
投票

这是一个闭包问题,我想你可以尝试这样做

func (s *MyStruct) PrintName() {
    fmt.Println(s.name)
}
© www.soinside.com 2019 - 2024. All rights reserved.