dongyun4010 2018-03-15 06:28
浏览 187
已采纳

go中的reflect.ValueOf(&x).Elem和reflect.ValueOf(x)有什么区别?

In my point of view, reflect.ValueOf(&x).Elem() is equal to reflect.ValueOf(x) because .Elem() is get the real value of the pointer that reflect.Value contains. Here comes the code, the encoding results by json.Marshal are different:

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))
}

And belowing is the output:

{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

I wonder why they are different, and how to modify my code to make the encoding result of request1 same as request2.

  • 写回答

1条回答 默认 最新

  • doujiaozhan2413 2018-03-15 07:05
    关注

    Sorry, this is all totally wrong. Reflection and JSON marshalling don't go together.

    The json2, err := json.Marshal(request2) part is sound: request2 is a Node (wrapped in interface{}, a fact not interesting here). So callong json.Marshal on it will marshal a Node and this result in {"cmd":"Netware","name":"123"} which is what you expect.

    Now for the json1, err := json.Marshal(request1Val): Go is statically typed and your request1Val is of type reflect.Value which is a complete normal type in Go like string or type myFoo struct {whatever}. If you pass something of this type to json.Marshal you'll get a JSON serialization of a reflect.Value. Unfortunately this serialization is totally useless in any way as it bears nothing in common with the value encapsulated in the reflect.Value. Think of reflect.Values as an opaque container containing your request1. Unfortunately it is opaque and serializing won't magically reveal what it is hiding.

    If you want to go from reflect.Value to what it actually holds use it's Interface() method to "unwrap" the container and get back what you wrapped in the reflect.Value.

    Your problem is unrelated to what reflect.ValueOf(&x).Elem() or reflect.Value(x) does (not) differently. Your problem stems from passing a reflect.Value to json.Marshal which will never work, no matter what the reflect.Value actually holds.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 求三轴之间相互配合画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站