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
.
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.