[英]What is the difference between reflect.ValueOf() and Value.Elem() in go?
[英]what's the difference between `reflect.ValueOf(&x).Elem` and `reflect.ValueOf(x)` in go?
在我看來, reflect.ValueOf(&x).Elem()
等於reflect.ValueOf(x)
因為.Elem()
是獲取reflect.Value
包含的指針的真實值。 這里是代碼, json.Marshal
的編碼結果是不同的:
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))
}
下面是輸出:
{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
我不知道為什么他們是不同的,以及如何修改我的代碼,以使編碼結果request1
一樣request2
。
抱歉,這完全是錯誤的。 反射和JSON編組不能同時使用。
json2, err := json.Marshal(request2)
部分是正確的: request2
是一個Node
(包裝在interface{}
,在這里並不有趣)。 因此,在其上的callong json.Marshal將封送一個Node
,這將導致您期望的是{"cmd":"Netware","name":"123"}
。
現在,對於json1, err := json.Marshal(request1Val)
:Go是靜態 類型的,而您的request1Val
類型是reflect.Value,這是Go中完整的普通類型,例如string
或type myFoo struct {whatever}
。 如果你通過這種類型的東西json.Marshal你會得到的JSON序列化reflect.Value
。 不幸的是,這種序列化在任何方面都是完全沒有用的,因為它與reflect.Value中封裝的值沒有任何共同之處。 可以將reflect.Values視為包含您的request1的不透明容器。 不幸的是,它是不透明的,序列化不會神奇地揭示它所隱藏的內容。
如果要從reflect.Value轉到其實際容納的內容,請使用其Interface()
方法“解包”容器並取回包裝在reflect.Value中的內容。
您的問題與reflect.ValueOf(&x).Elem()或reflect.Value(x)所做的(無關)無關。 您的問題源於將reflect.Value傳遞給json.Marshal,無論reflect.Value實際持有什么,它都將永遠無法工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.