接触 go 不久,有如下结构体:
type User struct {
UID int `json:"uid"`
Item string `json:"item"` // item 数据格式:{"f1":[1,2,3], "f2": [4,5,6]}
// ...
}
其中 Item 的值是一串 json,代码中好多地方需要操作这个 Item,每次操作的时候需要将其反序列化成对象,操作完了在序列化然后赋值给 Item
为了防止重复的写序列化和反序列化这两部分代码,我给 User 这个结构体绑上了两个方法:
func (u *User) UnmarshalItem(){
// ...
}
func (u *User) MarshalItem(){
// ...
}
这样每次只需要user.UnmarshalItem()
或者user.MarshalItem()
即可
后来发现这样还是避免不了频繁的序列化和反序列化,于是就给 User 再加一个反序列化后的属性,这样就不用每次都要反序列化了
type User struct {
UID int `json:"uid"`
Item string `json:"item"`
ItemObject map[string][]int `json:"itemObject"`
// ...
}
大佬们还有更好的解决方案吗?
其实我想实现这样的效果:
我在 User struct 里定义的时候 Item 的类型就是 map[string][]int,我想要获得 Item 的 json 的时候只需要 user.Item.String 就能获得了(这样好像得把 Item 也定义成结构体,然后再在 Item 这个结构体力定义 String,然后嵌套才行是不是)
1
reus 2019-07-09 12:58:19 +08:00 1
自定义一个类型,实现 json.Unmarshaler 接口
例子: https://play.golang.org/p/wuzKpNlHhf0 https://gist.github.com/reusee/8a13d522c281691258f4ed2d33d0b81b |
2
mcfog 2019-07-09 13:03:37 +08:00 via Android 2
问题是你的 json 报文里的 item 也是一个内容为字符串的 json,这是个很差的设计,即使改不了,也至少在输入输出的地方统一处理,不要把脏东西带到你的业务代码里面去
|
3
littlewing 2019-07-09 13:06:47 +08:00 1
嵌套有何不可?
|
4
dapang1221 2019-07-09 13:12:11 +08:00
你那个注释 // item 数据格式:{"f1":[1,2,3], "f2": [4,5,6]}
这个不对的吧,如果 item 是 string 的话,这个应该转义放在 item 里,像注释这样的话,item 就是 object,或者说是 struct 没错的啊……无论是 go 还是 php,反序列化的时候都不会只处理一部分的 |
5
imherer OP @reus 请教下,这句什么意思:var _ json.Unmarshaler = new(Item)
定义了一个“丢弃”的变量并赋值? |
6
imherer OP @dapang1221 嗯,注释的不对,应该是一个字符串 `{"f1":[1,2,3], "f2": [4,5,6]} `。这样的
|
7
reus 2019-07-09 13:27:10 +08:00 1
@imherer 这句用于保证 Item 实现了 json.Unmarshaler 接口。如果没实现,编译时就会报错,因为不能将 *Item 赋值到 json.Unmarshaler 类型的变量。变量名不重要,所以用 _
|
10
victrec 2019-07-09 14:38:15 +08:00
直接操作 json 呢? gjson sjson
|