指定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} 

playground

第二种方法是实现在房产类型的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 
} 

playground

+0

我知道这一点。正如你在我的例子中看到的那样。但我想为某些类型添加一些特定的格式。比方说,我希望日期为文本格式“星期一,三月第一”或我希望数字显示为“#45”。 – Topo 2014-10-02 21:47:43

+0

我没有看到有关实施Marshaler接口的更新。那就是我正在寻找的东西。非常感谢 – Topo 2014-10-03 14:25:25