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.

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

报告相同问题?

悬赏问题

  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)