2014-10-02 68 views
0

我有以下的結構,這是我使用與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的對象,然後編組對象。

有沒有這樣做的內置方式?如果沒有,是否有任何習慣做法呢?

回答

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} 

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