
本文旨在解决在使用Go语言的`encoding/json`包进行JSON反序列化时,遇到的“Unmarshal on reflected value”问题。通过示例代码,详细解释了如何正确地使用反射来动态地创建和填充对象,从而实现将JSON数据反序列化到指定类型的对象中。
在使用Go语言的encoding/json包进行JSON反序列化时,有时我们需要动态地创建对象并将其填充为JSON数据。这通常涉及到使用反射,但如果使用不当,可能会遇到“Unmarshal on reflected value”错误。本文将通过一个具体的示例,详细解释如何解决这个问题。
问题的核心在于,json.Unmarshal函数需要一个指向可修改值的指针。当我们使用reflect.New创建一个新的反射值时,需要确保传递给Unmarshal的是该值的地址,并且该值是可以被修改的。
以下是修改后的Get函数,它解决了上述问题:
func Get(a []byte, b interface{}) {
objType := reflect.TypeOf(b).Elem()
obj := reflect.New(objType).Interface()
MustJSONDecode(a, &obj)
fmt.Printf("obj = %#v\n", obj)
}代码解释:
完整示例代码:
Easily find JSON paths within JSON objects using our intuitive Json Path Finder
30
package main
import (
"encoding/json"
"fmt"
"reflect"
)
var (
datajson []byte
)
type User struct {
Name string
}
func MustJSONEncode(i interface{}) []byte {
result, err := json.Marshal(i)
if err != nil {
panic(err)
}
return result
}
func MustJSONDecode(b []byte, i interface{}) {
err := json.Unmarshal(b, i)
if err != nil {
panic(err)
}
}
func Store(a interface{}) {
datajson = MustJSONEncode(a)
}
func Get(a []byte, b interface{}) {
objType := reflect.TypeOf(b).Elem()
obj := reflect.New(objType).Interface()
MustJSONDecode(a, &obj)
fmt.Printf("obj = %#v\n", obj)
}
func main() {
dummy := &User{}
david := User{Name: "DavidMahon"}
Store(david)
Get(datajson, dummy)
}运行结果:
obj = &main.User{Name:"DavidMahon"}如果你的目标仅仅是将JSON反序列化到已经存在的对象中,更简单的方法是直接将JSON数据反序列化到该对象:
func Get(a []byte, b interface{}) {
MustJSONDecode(a, &b)
fmt.Printf("obj = %#v\n", b)
}这种方法避免了使用反射创建新对象,更加简洁高效。
通过本文,我们学习了如何使用反射来动态地创建对象并将其填充为JSON数据。关键在于理解reflect.New和.Interface()的用法,以及确保传递给json.Unmarshal的是一个指向可修改值的指针。同时,我们也了解了在不需要动态创建对象的情况下,更简洁的替代方案。希望本文能帮助你解决在使用Go语言进行JSON反序列化时遇到的问题。
以上就是使用反射进行JSON反序列化:解决Unmarshal到反射值的问题的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号