json - 在不使用临时结构的情况下实现 Unmarshaller
问题描述
下面有一个 Unmarshaller 实现,因为time.Unix
它只接受秒或纳秒,但我的数据源以毫秒为单位。在问我的问题之前,这里有一些代码
代码:
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
}
我的问题是
- 在这种情况下,有没有办法在不创建中间结构的情况下实现 Unmarshaller?如您所见,如果我使用 Platform 类型而不是中间结构,则会出现堆栈溢出错误。
- 这种方法最终会导致内存泄漏吗?
解决方案
您可以将编组器可以处理的字段组合为结构内的匿名结构Platform
,例如:
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"`
}
然后在自定义解组器中,解组到嵌套结构中,并设置其他值。
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
}
推荐阅读
- python - python的导入规则
- python - 呼叫转发循环而不是重定向
- mysql - 如何使用 perl 在 windows V10 上访问 mysql V8?
- c++ - 如果成员函数同时出现内联和非内联,编译器会做什么
- kotlin - Kotlin - 当使用 .. 创建范围或它如何执行比较时会发生什么?
- json - 如何解决这个 JQ 字符串连接问题?
- python - 如何在完全不同的函数中使用函数的返回值
- swift - 如何在两个视图控制器的两个特定实例之间来回移动,而不必每次都传递数据
- java - 我的 grails 项目使用 domain.save(flush:true).save() 面临错误“TransactionRequiredException:no transaction”,它可以保存但正在更新
- python - QPainter 混合颜色