如何解决如何在 go 中跳过 json.Marshal 字段而不是 json.Unmarshal 字段?
type Alpha struct {
Name string `json:"name"`
SkipwhenMarshal string `json:"skipwhenMarshal"`
}
func MarshalJSON(out interface{}){
json.Marshal(out)
}
在执行 json.Marshal 时是否可以忽略 SkipwhenMarshal 字段,但在执行时不能 json.解组。 它应该适用于任何调用 MarshalJSON
的类型解决方法
诸如“omitempty”和“-”之类的字段标记修饰符适用于编组和解组,因此没有自动方法。
您可以为您的类型实现一个 MarshalJSON
,忽略您需要的任何字段。无需实现自定义解组器,因为默认设置适合您。
例如像这样:
type Alpha struct {
Id int32
Name string
SkipWhenMarshal string
}
func (a Alpha) MarshalJSON() ([]byte,error) {
m := map[string]string{
"id": fmt.Sprintf("%d",a.Id),"name": a.Name,// SkipWhenMarshal *not* marshaled here
}
return json.Marshal(m)
}
您还可以通过使用别名类型使其更简单:
func (a Alpha) MarshalJSON() ([]byte,error) {
type AA Alpha
aa := AA(a)
aa.SkipWhenMarshal = ""
return json.Marshal(aa)
}
此处将输出 SkipWhenMarshal
,但其值已清零。这种方法的优点是,如果 Alpha
有很多字段,您不必重复它们。
你想要的根本无法通过 encoding/json 来完成。
但是你可以有两种类型
type AlphaIn struct {
Name string `json:"name"`
Bar string `json:"skipWhenMarshal"`
}
type AlphaOut struct {
Name string `json:"name"`
Bar string `json:"-"`
}
使用 AlphaIn
使用 encoding/json.Unmarshal 反序列化 JSON,并使用 AlphaOut
使用 encoding/json.Marshal 将结构序列化为 JSON。
现在单独使用这将是绝对痛苦的,但是:结构标记在类型之间的可转换性中不起作用,这使您可以通过简单的类型转换从 AlphaIn 转换为 AlphaOut:
var a AlphaIn = ...
var b AlphaOut = AlphaOut(a)
(更合理的命名方案应该是 Alpha
和 AlphaToJSON
或类似的东西。)
我会像这样编写一个自定义的 marshal 函数:playground
package main
import (
"encoding/json"
"fmt"
"reflect"
"strings"
)
type Alpha struct {
Name string `json:"name"`
SkipWhenMarshal string `json:"SkipWhenMarshal,skip"`
}
func main() {
var a Alpha
a.Name = "John"
a.SkipWhenMarshal = "Snow"
out,_ := marshal(a)
fmt.Println(string(out))
var b Alpha
json.Unmarshal([]byte(`{"Name":"Samwell","SkipWhenMarshal":"Tarly"}`),&b)
fmt.Println(b)
}
// custom marshaling function for json that accepts an additional tag named skip to ignore the field
func marshal(v Alpha) ([]byte,error) {
m := map[string]interface{}{}
ut := reflect.TypeOf(v)
uv := reflect.ValueOf(v)
for i := 0; i < ut.NumField(); i++ {
field := ut.Field(i)
js,ok := field.Tag.Lookup("json")
if !ok || !strings.Contains(js,"skip") {
intf := uv.Field(i).Interface()
switch val := intf.(type) {
case int,int8,uint8:
m[field.Name] = val
case string:
m[field.Name] = val
}
}
}
return json.Marshal(m)
}
它基本上将结构重建为没有跳过字段的映射,并将其传递给原始 Marshal 函数。
现在只需将 SKIP 标签添加到任何字段,它就可以工作了。
你只需要改进这部分:
switch val := intf.(type) {
因为这仅假设您只有字符串或整数作为字段。处理更多类型会更理想。
,你可以试试这个,即将结构分解成组件 -> 组合
解组时使用 Beta 类型。它只会解组 Beta 结构中定义的字段
type Beta struct {
Name string `json:"name"`
}
type Alpha struct {
*Beta
SkipWhenMarshal string `json:"skipWhenMarshal"`
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。