V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
imherer
V2EX  ›  Go 编程语言

请教一个 go 结构体问题

  •  
  •   imherer · 2019-07-09 12:26:19 +08:00 · 2528 次点击
    这是一个创建于 1752 天前的主题,其中的信息可能已经有所发展或是发生改变。

    接触 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,然后嵌套才行是不是)

    11 条回复    2019-07-09 14:40:13 +08:00
    reus
        1
    reus  
       2019-07-09 12:58:19 +08:00   ❤️ 1
    mcfog
        2
    mcfog  
       2019-07-09 13:03:37 +08:00 via Android   ❤️ 2
    问题是你的 json 报文里的 item 也是一个内容为字符串的 json,这是个很差的设计,即使改不了,也至少在输入输出的地方统一处理,不要把脏东西带到你的业务代码里面去
    littlewing
        3
    littlewing  
       2019-07-09 13:06:47 +08:00   ❤️ 1
    嵌套有何不可?
    dapang1221
        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,反序列化的时候都不会只处理一部分的
    imherer
        5
    imherer  
    OP
       2019-07-09 13:18:09 +08:00
    @reus 请教下,这句什么意思:var _ json.Unmarshaler = new(Item)
    定义了一个“丢弃”的变量并赋值?
    imherer
        6
    imherer  
    OP
       2019-07-09 13:19:34 +08:00
    @dapang1221 嗯,注释的不对,应该是一个字符串 `{"f1":[1,2,3], "f2": [4,5,6]} `。这样的
    reus
        7
    reus  
       2019-07-09 13:27:10 +08:00   ❤️ 1
    @imherer 这句用于保证 Item 实现了 json.Unmarshaler 接口。如果没实现,编译时就会报错,因为不能将 *Item 赋值到 json.Unmarshaler 类型的变量。变量名不重要,所以用 _
    imherer
        8
    imherer  
    OP
       2019-07-09 13:30:50 +08:00
    @reus 你的号是不是被降权了,你的回复在新消息提醒列表里不出现
    reus
        9
    reus  
       2019-07-09 13:31:57 +08:00
    @imherer 不知道
    victrec
        10
    victrec  
       2019-07-09 14:38:15 +08:00
    直接操作 json 呢? gjson sjson
    imherer
        11
    imherer  
    OP
       2019-07-09 14:40:13 +08:00
    @victrec 直接操作 json 也可以,不过这个库用的不太熟,感觉直接操作字符串没有操作对象保险
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3385 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 11:51 · PVG 19:51 · LAX 04:51 · JFK 07:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.