Json Unmarshal reflect.Type

huangapple go评论82阅读模式
英文:

Json Unmarshal reflect.Type

问题

以下是代码的翻译结果:

package main

import (
	"fmt"

	"encoding/json"
	"reflect"
)

var (
	datajson []byte
)

type User struct {
	Name string
	Type reflect.Type
}

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)
	fmt.Println(datajson)
}

func Get(a []byte, b interface{}) {
	MustJSONDecode(a, b)
	fmt.Println(b)
}

func main() {
	dummy := &User{}
	david := &User{Name: "DavidMahon"}
	typ := reflect.TypeOf(david)
	david.Type = typ
	Store(david)
	Get(datajson, dummy)
}

我可以成功地将reflect.Type进行编组(marshal),但是当我进行反向操作时,会出现错误。我知道reflect.Type是一个接口。那么我在这里做错了什么?如何安全地存储reflect.Type的值,并将其重新获取回来?

英文:

Here is the code:

package main

import (
    "fmt"

    "encoding/json"
    "reflect"
)

var(
    datajson []byte
)

type User struct {
    Name string
    Type reflect.Type
}

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)
    fmt.Println(datajson)
}

func Get(a []byte, b interface{}) {
    MustJSONDecode(a, b)
    fmt.Println(b)
}

func main() {
    dummy := &User{}
    david := &User{Name: "DavidMahon"}
    typ := reflect.TypeOf(david)
    david.Type = typ
    Store(david)
    Get(datajson, dummy)
}

I can successfully marshal reflect.Type but when I do the reverse, it panics. I know reflect.Type is an interface. So what am I doing wrong here? How can I store a reflect.Type value in json and then retrieve back safely?

答案1

得分: 1

这没有意义。JSON包无法知道应该解码哪些数据。这个接口可能由struct{}类型、int类型和struct{ Value1, Value2 int }类型实现。更糟糕的是,可能还有其他类型,它们甚至不是你的二进制文件的一部分(缺少导入、死代码消除等)。那么,你希望从JSON中得到哪种类型的返回值呢?

你可能需要找到另一种方法。例如,你可以实现json.Unmarshaler接口,解组一个标识符,并使用该标识符将后续的数据解组为具体类型。你可能需要使用switch语句来实现这一点,这也将确保具体类型是你的二进制文件的一部分(因为你在使用它)。

但可能有一个更简单的解决方案。不过,你的问题没有说明你想要实现什么。只将类型的名称作为字符串进行编组/解组是否足够?

英文:

That doesn't make sense. There is no way for the JSON package to know what data should be decoded. This interface might be implemented by a struct{} type, an int type and maybe a struct{ Value1, Value2 int } type. Even worse, there might be other types as well, that are aren`t even part of your binary (missing imports, dead code elimination, etc.). So, which type do you expect to get back from JSON?

You probably need to find another way. For example, you could implement the json.Unmarshaler interface, unmarshal an identifier and use that identifier to unmarshal the following data into a concrete type. The switch statement that you will probably need for that, will also ensure that the concrete type is part of your binary (since you are using it).

But there is probably an easier solution. Your question doesn't tell what you want to archive though. Would it be enough to just marshal / unmarshal the name of the type as string?

huangapple
  • 本文由 发表于 2013年8月18日 02:22:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/18291993.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定