代码之家  ›  专栏  ›  技术社区  ›  vinllen

“反射”和“反射”有什么区别。值(&x)。元素和反映。ValueOf(x)`在go中?

  •  2
  • vinllen  · 技术社区  · 8 年前

    在我看来, reflect.ValueOf(&x).Elem() 等于 reflect.ValueOf(x) 因为 .Elem() 获取指针的实际值 reflect.Value 包含。下面是代码,编码结果为 json.Marshal 是不同的:

    func generateRequest(input string, flag bool) interface{} {
        val := Node {
            Cmd: "Netware",
            Name: input,
        }
        if flag {
            return &val
        } else {
            return val
        }
    }
    
    func main() {
        request1 := generateRequest("123", true)
        request2 := generateRequest("123", false)
    
        request1Val := reflect.ValueOf(request1).Elem()
        fmt.Println(request1Val, request2)
    
        json1, err := json.Marshal(request1Val)
        checkErr(err)
        json2, err := json.Marshal(request2)
        checkErr(err)
    
        fmt.Println(json1, string(json1))
        fmt.Println(json2, string(json2))
        fmt.Println(reflect.DeepEqual(json1, json2))
    }
    

    以下是输出:

    {Netware 123} {Netware 123}
    [123 34 102 108 97 103 34 58 52 48 57 125] {"flag":409}
    [123 34 99 109 100 34 58 34 78 101 116 119 97 114 101 34 44 34 110 97 109 101 34 58 34 49 50 51 34 125] {"cmd":"Netware","name":"123"}
    false
    

    我想知道为什么它们不同,以及如何修改我的代码以使 request1 与相同 request2

    1 回复  |  直到 8 年前
        1
  •  2
  •   Volker    8 年前

    对不起,这完全错了。反射和JSON编组不能同时进行。

    这个 json2, err := json.Marshal(request2) 零件完好: request2 是一个 Node (包裹在 interface{} ,这一事实在这里并不有趣)。所以callong json。对其进行封送将封送 节点 这导致 {"cmd":"Netware","name":"123"} 这就是你所期望的。

    现在是 json1, err := json.Marshal(request1Val) :Go是 静态地 键入的 还有你的 request1Val 属于reflect类型。值,该值在Go like中是完全正常类型 string type myFoo struct {whatever} 。如果您将这种类型的内容传递给json。封送处理您将得到 reflect.Value 。不幸的是,这种序列化在任何方面都是毫无用处的,因为它与reflect中封装的值没有任何共同之处。价值想想反思。值作为包含request1的不透明容器。不幸的是,它是不透明的,序列化并不能神奇地揭示它隐藏的内容。

    如果你想从reflect开始。实际拥有的价值使用它的 Interface() 方法“展开”容器并取回您在反射中包装的内容。价值

    你的问题与反映的内容无关。值(&x)。Elem()或reflect。值(x)没有(没有)不同。你的问题源于通过反思。json的值。元帅将 从不 工作,无论反映什么。值实际有效。