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

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.

    点赞 打赏 评论

相关推荐 更多相似问题