簡體   English   中英

go中的reflect.ValueOf(&x).Elem和reflect.ValueOf(x)有什么區別?

[英]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中完整的普通類型,例如stringtype 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM