编码/解码后的结构变化

huangapple go评论85阅读模式
英文:

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.ValueBis 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.

huangapple
  • 本文由 发表于 2017年2月9日 18:27:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/42134152.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定