我有以下结构,用于与API通信:
type Object struct {
Id uint64
Type string
Class string
Properties []Property
}
type Property struct {
Name string
DataType string
Value interface{}
}
我在发送之前使用json.MarshalIndent()
将我的结构转换为json。这给了我类似的东西:
{
"Id": 15,
"Type": "Node",
"Class": "Persona",
"Properties": [
{
"Name": "Nombre",
"DataType": "text",
"Value": "Oso"
},
{
"Name": "Edad",
"DataType": "int",
"Value": 45
},
{
"Name": "Fecha de Naciemiento",
"DataType": "date",
"Value": "1989-09-27T05:30:08-06:00"
}
]
}
我希望在编组之前格式化value
值(因为它的类型为interface{}
我需要根据值类型格式化它)。
我遇到的第一个解决方案是创建(Object) encode() string
函数或其他东西,迭代[]Property
格式化值,并分别编组每个属性,然后使用{{1重构对象而不是[]string
,然后编组对象。
有没有内置的方法呢?如果没有,是否有任何惯用的方式呢?
答案 0 :(得分:1)
JSON编码器根据值的实际类型编组接口{}值。您可以通过多种方式覆盖默认编码。
第一种是围绕值创建一个包装器,以控制使用Marshaler interface对它们进行编码的方式。这是一个改变整数编码方式的包装器:
type Value struct{ Value interface{} }
func (v Value) MarshalJSON() ([]byte, error) {
switch v := v.Value.(type) {
case int:
return []byte(fmt.Sprintf("\"#%d\"", v)), nil
default:
return json.Marshal(v)
}
}
像这样使用:
prop.Value = Value{45}
第二种方法是在Property类型上实现Marshaler以覆盖所有属性的封送方式,包括Value字段。
func (p Property) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer
buf.WriteString(`{"Name":`)
d, err := json.Marshal(p.Name)
if err != nil {
return nil, err
}
buf.Write(d)
buf.WriteString(`,"DataType":`)
d, err = json.Marshal(p.DataType)
if err != nil {
return nil, err
}
buf.Write(d)
buf.WriteString(`, "Value":`)
switch v := p.Value.(type) {
case int:
fmt.Fprintf(&buf, "\"#%d\"", v)
default:
d, err := json.Marshal(v)
if err != nil {
return nil, err
}
buf.Write(d)
}
buf.WriteString("}")
return buf.Bytes(), nil
}