英文:
Struct changes after encode/decode
问题
我目前遇到的问题是,将一个结构体保存到 JSON 文件中,然后从 JSON 文件中打开结构体后,结构体的属性发生了轻微的变化。
在结构体 N 中,有时 A 和 B 可能指向同一个 J。然而,在编码和解码之后,它们指向了不同值的 J。
在编码之前,这个语句返回 true(预期结果)。但在解码之后,它返回 false(不是预期结果)。
这种情况是否正常?是否有办法解决这个问题?谢谢。
type N struct {
A []*J
B []*J
C []*J
}
func (n *N) Save(name string) {
name = "redacted.json"
err := os.Remove(name)
file, err := os.Create(name)
defer file.Close()
if err != nil {
fmt.Println(err)
}
bytes, err := json.Marshal(n)
file.Write(bytes)
}
func Open(name string) *N {
bytes, err := ioutil.ReadFile("redacted.json")
if err != nil {
log.Fatal("decode error:", err)
}
var n N
json.Unmarshal(bytes, &n)
return &n
}
英文:
The problem I'm currently having is after saving a struct to a json file and then opening the struct from the json file, somehow the properties of the struct have changed slightly.
In the struct N, sometimes A and B can point to the same J. However, after encoding then decoding they point to different Js of the value.
before encoding this returns true (expected). After decoding it, it returns false (not expected)
fmt.Println("is same pointer", n.A[0] == n.B[0])
Is this supposed to happen? Is there a way around this. Thanks.
type N struct {
A []*J
B []*J
C []*J
}
func (n *N) Save(name string) {
name = "radacted.json"
err := os.Remove(name)
file, err := os.Create(name)
defer file.Close()
if err != nil {
fmt.Println(err)
}
bytes, err := json.Marshal(n)
file.Write(bytes)
}
func Open(name string) *N {
bytes, err := ioutil.ReadFile("redacted.json")
if err != nil {
log.Fatal("decode error:", err)
}
var n NeuralNetwork
json.Unmarshal(bytes, &n)
return &n
}
答案1
得分: 3
这是预期的和有文档记录的行为。
指针值编码为所指向的值。
你可以断言值的相等性:
*n.A[0] == *n.B[0] //应该保持不变
英文:
It's expected and documented behaviour
> Pointer values encode as the value pointed to.
You can assert values equality
*n.A[0] == *n.B[0] //should stay
答案2
得分: 1
你在这里比较的是地址值,所以它们不会相同。让我给你举个例子,假设你有这样的结构体:
type Test struct {
ValueA *int
ValueB *int
}
在你的主函数中,你使用不同的变量地址添加了相同的值:
func main() {
hello := 12
hello2 := 12
testObject := Test{ValueA: &hello, ValueB: &hello2}
if *testObject.ValueA == *testObject.ValueB {
fmt.Println("Equal Value")
} else {
fmt.Println("Different Value")
}
}
注意,*testObject.ValueA
和*testObject.ValueB
获取的是确切的值,而不是值的地址。如果你不使用*
,结果将会不同。
所以,正如uvelichitel所说,当比较结构体的值时,你只需要使用*
即可。
英文:
> fmt.Println("is same pointer", n.A[0] == n.B[0])
you are comparing the address value here so it will not be the same. Let me give you an example
suppose you have struct like this :
type Test struct {
ValueA *int
ValueB *int
}
and on your main function you add the same value but with different address in this case with different variable :
func main() {
hello := 12
hello2 := 12
testObject := Test{ValueA: &hello, ValueB: &hello2}
if *testObject.ValueA == *testObject.ValueB {
fmt.Println("Equal Value")
} else {
fmt.Println("Different Value")
}
}
Notice that the *testObject.ValueA
and *testObject.ValueB
is getting the exact value not the value address. If you are not using *
the result would be different.
so as uvelichitel said you just need to use *
when comparing your struct value.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论