doudeng1870 2018-08-11 18:16
浏览 19
已采纳

在不使用临时结构的情况下实现Unmarshaller

There is an Unmarshaller implementation down below because of time.Unix does only accepts seconds or nanoseconds but my data source is in milliseconds. Before asking my questions here is some code

Code:

type Platform struct {
    Status                CampaignStatus `json:"status" bson:"status"`
    TotalBudget           int            `json:"total_budget" bson:"totalBudget"`
    RemainingBudget       int            `json:"remaining_budget" bson:"remainingBudget"`
    MillisecondsStartDate int64          `json:"start_date"`
    StartDate             time.Time      `bson:"startDate"`
    MillisecondsEndDate   int64          `json:"end_date"`
    EndDate               time.Time      `bson:"endDate"`
    Audiance              Audiance       `json:"target_audiance" bson:"targetAudiance"` //typo?
    Creatives             Creatives      `json:"creatives" bson:"Creatives"`
    Insights              Insights       `json:"insights" bson:"insights"`
}

func (p *Platform) UnmarshalJSON(b []byte) (err error) {

    p2 := struct {
        Status                CampaignStatus `json:"status" bson:"status"`
        TotalBudget           int            `json:"total_budget" bson:"totalBudget"`
        RemainingBudget       int            `json:"remaining_budget" bson:"remainingBudget"`
        MillisecondsStartDate int64          `json:"start_date"`
        StartDate             time.Time      `bson:"startDate"`
        MillisecondsEndDate   int64          `json:"end_date"`
        EndDate               time.Time      `bson:"endDate"`
        Audiance              Audiance       `json:"target_audiance" bson:"targetAudiance"` //typo?
        Creatives             Creatives      `json:"creatives" bson:"Creatives"`
        Insights              Insights       `json:"insights" bson:"insights"`
    }{}

    err = json.Unmarshal(b, &p2)
    if err != nil {
        return
    }

    p2.StartDate = time.Unix(0, p2.MillisecondsStartDate*int64(time.Millisecond/time.Nanosecond))
    p2.EndDate = time.Unix(0, p2.MillisecondsEndDate*int64(time.Nanosecond/time.Microsecond))

    *p = p2

    return
}

My questions are

  1. Is there a way to implement Unmarshaller without creating a middle struct in this scenario? As you may see if I use the Platform type isntead of middle struct I get stack overflow error.
  2. Could this approach ends up with memory leaks?
  • 写回答

2条回答 默认 最新

  • dongqieli4164 2018-08-13 09:48
    关注

    You could compose the fields that the marshaller can handle as an anonymous struct inside the Platform struct, something like:

    type platformInner struct {
        Status                CampaignStatus `json:"status" bson:"status"`
        TotalBudget           int            `json:"total_budget" bson:"totalBudget"`
        RemainingBudget       int            `json:"remaining_budget" bson:"remainingBudget"`
        MillisecondsStartDate int64          `json:"start_date"`
    
        MillisecondsEndDate   int64          `json:"end_date"`
    
        Audiance              Audiance       `json:"target_audiance" bson:"targetAudiance"` //typo?
        Creatives             Creatives      `json:"creatives" bson:"Creatives"`
        Insights              Insights       `json:"insights" bson:"insights"`
    }
    
    type Platform struct {
        platformInner
        StartDate             time.Time      `bson:"startDate"`
        EndDate               time.Time      `bson:"endDate"`
    }
    

    And then in the custom unmarshaller, unmarshal into the nested struct, and set the other values.

    func (p *Platform) UnmarshalJSON(b []byte) (err error) {
        var inner platformInner
        err = json.Unmarshal(b, &inner)
        if err != nil {
            return
        }
    
        tmp := &Platform{
            innerPlatform: inner,
            StartDate:     time.Unix(0, inner.MillisecondsStartDate*int64(time.Millisecond/time.Nanosecond))
            EndDate:       time.Unix(0, inner.MillisecondsEndDate*int64(time.Nanosecond/time.Microsecond))
        }
    
        *p = tmp
    
        return
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害