这是我正在尝试编写的真实世界代码的一部分。问题是Go复制了接口sibling
,所以我无法修改数据。但是,如果我改为使用指向接口的指针,那么相等的概念就会失败。我知道我可以使用DeapEquals
,但不能使用地图。
package main
import (
"fmt"
)
type Q interface {
modify()
}
type P struct {
name string
sibling Q
}
func (x P) modify() {
x.name = "a"
}
func main() {
a := P{"a", nil}
A := P{"?", nil}
b := P{"b", a}
B := P{"b", A}
B.sibling.modify()
fmt.Println(B)
fmt.Println(b == B)
}
如何让Go让我自己修改界面数据而不复制它并修改副本?
似乎这些在结构上是互斥的:
答案 0 :(得分:3)
修改数据而不复制数据的唯一方法是使用指针。
我对你所说的内容感到有点困惑,因为你的例子使用了一个结构,然后你谈论了结构,但是你说你需要能够使用地图。无论哪种方式,DeepReflect都适用于这两种方式。 Here是您修改为使用指针的示例:
package main
import (
"fmt"
"reflect"
)
type Q interface {
modify()
}
type P struct {
name string
sibling Q
}
func (x *P) modify() {
x.name = "a"
}
func main() {
a := P{"a", nil}
A := P{"?", nil}
b := P{"b", &a}
B := P{"b", &A}
B.sibling.modify()
fmt.Println("a:", a)
fmt.Println("A:", A)
fmt.Println("b:", b)
fmt.Println("B:", B)
fmt.Println(b == B)
fmt.Println(reflect.DeepEqual(b, B))
}
打印:
a: {a <nil>}
A: {a <nil>}
b: {b 0x10436180}
B: {b 0x10436190}
false
true
你可以看到this帖子对地图做同样的事情。
答案 1 :(得分:0)
您可以使用modify()
返回的值package main
import (
"fmt"
)
type Q interface {
modify() Q //See here
}
type P struct {
name string
sibling Q
}
func (x P) modify() Q{ //Here
x.name = "a"
return x
}
func main() {
a := P{"a", nil}
A := P{"?", nil}
b := P{"b", a}
B := P{"b", A}
B.sibling=B.sibling.modify() //And here
fmt.Println(B)
fmt.Println(b == B)
}
它有点冗长,但至少有效https://play.golang.org/p/8oM90wriN0