指定json.Marshal结构格式()
问题描述:
我有以下的结构,这是我使用与API进行通信:指定json.Marshal结构格式()
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
迭代格式化的值,并且分别编组的每个属性,然后重构与[]string
代替[]Property
的对象,然后编组对象。
有没有这样做的内置方式?如果没有,是否有任何习惯做法呢?
答
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}
第二种方法是实现在房产类型的Marshaler覆盖所有的财产是如何编组的,包括价值领域。
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
}
我知道这一点。正如你在我的例子中看到的那样。但我想为某些类型添加一些特定的格式。比方说,我希望日期为文本格式“星期一,三月第一”或我希望数字显示为“#45”。 – Topo 2014-10-02 21:47:43
我没有看到有关实施Marshaler接口的更新。那就是我正在寻找的东西。非常感谢 – Topo 2014-10-03 14:25:25