Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 在围棋中,你如何把棋子解到正确的顺序?_Json_Go_Marshalling_Unmarshalling - Fatal编程技术网

Json 在围棋中,你如何把棋子解到正确的顺序?

Json 在围棋中,你如何把棋子解到正确的顺序?,json,go,marshalling,unmarshalling,Json,Go,Marshalling,Unmarshalling,看起来,如果我有一个接口{}以特定的顺序在Go中,我将它封送到一个[]字节,然后将它反封送回接口{},它应该保持原始顺序。事实并非如此。结果是,正如您在下面的程序中看到的,DeepEqual无法匹配这两个 package main import ( "encoding/json" "fmt" "reflect" ) func main() { var jd interface{} j := map[string]interface{}{

看起来,如果我有一个接口{}以特定的顺序在Go中,我将它封送到一个[]字节,然后将它反封送回接口{},它应该保持原始顺序。事实并非如此。结果是,正如您在下面的程序中看到的,DeepEqual无法匹配这两个

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

func main() {
    var jd interface{}

    j := map[string]interface{}{
        "A": map[string]interface{}{"a": 1, "b": 2, "c": 3},
        "B": map[string]interface{}{"a": 1, "b": 2, "c": 3},
        "C": map[string]interface{}{
            "a": map[string]interface{}{"a": 1, "b": 2, "c": 3},
            "b": map[string]interface{}{"a": 1, "b": 2, "c": 3},
            "c": map[string]interface{}{"a": 1, "b": 2, "c": 3},
        },
    }

    s, _ := json.Marshal(j)
    _ = json.Unmarshal(s, &jd)

    fmt.Println(string(s))
    fmt.Println(j)
    fmt.Println(jd)
    if !reflect.DeepEqual(j, jd) {
        fmt.Println("Fail!")
    }
}
该程序的结果是随机的,但这是一个典型的结果:

{"A":{"a":1,"b":2,"c":3},"B":{"a":1,"b":2,"c":3},"C":{"a":{"a":1,"b":2,"c":3},"b":{"a":1,"b":2,"c":3},"c":{"a":1,"b":2,"c":3}}}

map[B:map[a:1 b:2 c:3] C:map[c:map[a:1 b:2 c:3] a:map[b:2 c:3 a:1] b:map[a:1 b:2 c:3]] A:map[c:3 a:1 b:2]]

map[A:map[a:1 b:2 c:3] B:map[a:1 b:2 c:3] C:map[b:map[c:3 a:1 b:2] c:map[a:1 b:2 c:3] a:map[a:1 b:2 c:3]]]

Fail!
如您所见,这些值编组为原始顺序,但解编组为随机顺序(此程序的多次运行将产生不同的结果)。结果是DeepEqual比较每次都失败(到目前为止)

这是围棋中的虫子吗?是否有人可以建议解决方案

映射上的迭代顺序没有指定,也不能保证 从一次迭代到下一次迭代都是一样的


根据设计,映射上的迭代顺序是伪随机的。

映射的顺序不是它不相等的原因。(如果两次解组,将得到两个完全相等的贴图,它们的顺序仍然随机不同。)

:

如果您按以下方式更改代码,它将起作用:

var num float64 = 0;
j := map[string]interface{}{
    "A": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
    "B": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
    "C": map[string]interface{}{
        "a": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
        "b": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
        "c": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
    },
}

然后,您可以将num的类型更改为任何其他类型,它将失败。

必须强烈反对此答案。迭代器顺序不能解释差异:
reflect.DeepEqual
完全能够比较映射。从第116行开始的实现表明映射比较不受迭代顺序的影响。lossleader的回答是正确的。也就是说,这助长了一种错误的假设,即最初的提问者对
reflect.DeepEqual
的行为有误解。提问者将这种不平等归因于观察到这两个值的打印方式不同。实际上,重要的是数字类型的差异
reflect.DeepEqual
不关心如何打印值。我已经用您建议的更改进行了测试,它确实通过了DeepEqual,尽管显示的映射顺序不同。谢谢你的帮助。一个有趣的注意事项是,尽管显示顺序不正确,但如果封送回字符串,顺序始终会恢复。换句话说,在内部,数据必须是原始顺序。只有println显示出了问题。我必须确定一下,但真正的go是在编组时进行排序以规范化json格式:因此相当多的go结构(就类型而言)映射到特定的json表示,然后可以将其解组到特定的go结构(就类型而言)在运行时迭代期间仍然具有随机排序的映射。。强排序+松散排序和强排序+松散排序之间的有趣界面。
var num float64 = 0;
j := map[string]interface{}{
    "A": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
    "B": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
    "C": map[string]interface{}{
        "a": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
        "b": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
        "c": map[string]interface{}{"a": num+1, "b": num+2, "c": num+3},
    },
}