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.

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

报告相同问题?

悬赏问题

  • ¥15 宇视监控服务器无法登录
  • ¥15 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥15 DruidDataSource一直closing
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥50 power BI 从Mysql服务器导入数据,但连接进去后显示表无数据