英文:
golang Unmarshall Struct In Function that do not know the type and rely on interface
问题
这是我需要做的事情,但找不到所需的资源来完成它:
我需要编写一个通用函数,用于设置MOCK服务器的处理程序。该处理程序将接收一个JSON对象,并且必须对其进行解组并将其与参考结构进行比较,并根据两个对象之间的对应关系设置其状态。
这是关键:在函数内部,我们不知道参考的类型是什么。
<===== 我在这一点上是什么情况 ====>
我编写了这个不起作用的函数。
func createHandlerToTestDelete(route string, ref interface{}, received interface{}){
Servmux.HandleFunc(route,
func(w http.ResponseWriter, r *http.Request) {
// 从请求体中重新创建一个结构体
body, _ := ioutil.ReadAll(r.Body)
json.Unmarshal(body, &received)
// ref 和 received 进行比较
if reflect.DeepEqual(received, ref) {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
},
)
}
这是我如何使用它的方式:
ref := MyStruct{...NotEmpty...}
received := MyStruct{}
createHandlerToTestDelete("aRoute", ref, received)
结果是,当服务器执行解组操作时,不会关心接收变量的原始类型。
有人有什么想法吗?
英文:
here is what I need to do and can't find the resource I need in order to do it:
I need to write a generic function that will setup a handler for a MOCK server. This handler will receive a JSON object and have to unMarshall it and compare it to a reference structure and set its status accordingly depending on the correspondence between both object.
Here is the trick: we do not know inside the function what is the type of the reference.
<===== Where am I at this point ====>
I wrote this function, which doesn't work.
func createHandlerToTestDelete(route string, ref interface{}, received interface{}){
Servmux.HandleFunc(route,
func(w http.ResponseWriter, r *http.Request) {
// recreate a structure from body content
body, _ := ioutil.ReadAll(r.Body)
json.Unmarshal(body, &received)
// comparison between ref and received
if reflect.DeepEqual(received, ref) {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
},
)
}
here is how I am using it:
ref := MyStruct{...NotEmpty...}
received := MyStruct{}
createHandlerToTestDelete("aRoute", ref, received)
The result is that the server when doing Unmarshal will not care of the original type of the received variable.
Does someone has an idea?
答案1
得分: 1
使用reflect.New来创建一个与引用类型相同的值的指针。
func createHandlerToTestDelete(route string, ref interface{}) {
t := reflect.TypeOf(ref)
ServeMux.HandleFunc(route,
func(w http.ResponseWriter, r *http.Request) {
v := reflect.New(t)
if err := json.NewDecoder(r.Body).Decode(v.Interface()); err != nil {
// 处理错误
}
// v 是值的指针。获取元素以进行正确的比较。
if reflect.DeepEqual(v.Elem().Interface(), ref) {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
},
)
}
英文:
Use reflect.New to create a pointer to a value with the same type as the reference type.
func createHandlerToTestDelete(route string, ref interface{}) {
t := reflect.TypeOf(ref)
ServeMux.HandleFunc(route,
func(w http.ResponseWriter, r *http.Request) {
v := reflect.New(t)
if err := json.NewDecoder(r.Body).Decode(v.Interface()); err != nil {
// handle error
}
// v is pointer to value. Get element for correct comparison.
if reflect.DeepEqual(v.Elem().Interface(), ref) {
w.WriteHeader(http.StatusOK)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
},
)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论