gpt4 book ai didi

go - go中 `reflect.ValueOf(&x).Elem`和 `reflect.ValueOf(x)`有什么区别?

转载 作者:行者123 更新时间:2023-12-02 18:47:40 26 4
gpt4 key购买 nike

在我看来, 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){},这个事实在这里并不有趣)。因此,在其上调用 json.Marshal 将编码一个 Node ,这会导致 {"cmd":"Netware","name":"123"} ,这就是您想要的期待。

现在对于 json1, err := json.Marshal(request1Val):Go 是静态 类型化,而你的 request1Val 的类型为reflect.Value,它是Go 中完整的普通类型,如stringtype myFoo struct {whatever}。如果将这种类型的内容传递给 json.Marshal,您将获得 reflect.Value 的 JSON 序列化。不幸的是,这种序列化在任何方面都是完全无用的,因为它与 Reflect.Value 中封装的值没有任何共同之处。将 Reflect.Values 视为包含您的请求的不透明容器1。不幸的是,它是不透明的,序列化不会神奇地揭示它隐藏的内容。

如果您想从reflect.Value转到它实际保存的内容,请使用它的Interface()方法来“解开”容器并取回您在reflect.Value中包装的内容。

您的问题与reflect.ValueOf(&x).Elem()或reflect.Value(x)的不同之处无关。您的问题源于将reflect.Value传递给json.Marshal,无论reflect.Value实际包含什么,它都永远不会工作。

关于go - go中 `reflect.ValueOf(&x).Elem`和 `reflect.ValueOf(x)`有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49292854/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com