编组到json时转换类型

时间:2018-06-04 21:15:08

标签: json mongodb go marshalling

我的问题与this one非常相似,但不是将float64转换为使用string tag处理的string。在我的情况下,我正在尝试使用ObjectID方法将.Hex()转换为字符串。反之亦然,在返回途中使用.FromHex()函数。

但是,更一般地说,我如何从X类型转换为Y类型&回到Marshal& Unmarshal ING?

我的例子:

package main

import (
    "log"
    "fmt"
    "encoding/json"
    "github.com/mongodb/mongo-go-driver/bson/objectid"
)

type Greeting struct {
    Id          *objectid.ObjectID  `json:"id"`
    Greeting    string              `json:"greeting,omitempty"`
}


func main() {
    // Create ObjectID
    id, err := objectid.FromHex("5b14dd20f6418c8443a5ffec")
    if err != nil { log.Fatal(err) }

    // Create Greeting
    g := Greeting{&id, "Hello, World!"}

    // Marshal to json
    j, err := json.Marshal(g)
    if err != nil { log.Fatal(err) }

    // Print Json
    fmt.Printf("Json: %s", string(j))

}

输出:

Json: {"id":[91,20,221,32,246,65,140,132,67,165,255,236],"greeting":"Hello, World!"}

然而,我想要的是:

Json: {"id":"5b14dd20f6418c8443a5ffec","greeting":"Hello, World!"}

2 个答案:

答案 0 :(得分:2)

您应该编写自己的(联合国)编组功能,在其中处理转换/条件并在调用json(un)编组时将其作为参数处理。

type Whatever struct {
   someField int
}

func (w Whatever) MarshalJSON() ([]byte, error) {
    return json.Marshal(struct{
        SomeField int `json:"some_field"`
    }{
        SomeField: w.someField,
    })
}

func (w Whatever) MarshalJSON() ([]byte, error) {
   return json.Marshal(map[string]interface{}{
       "some_field": w.SomeField,
   })
}

答案 1 :(得分:2)

您可以将objectid.ObjectId的命名类型声明为实现json.Marshaler接口以覆盖标准编组并输出十六进制字符串:

type Id objectid.ObjectId

func (id Id) MarshalJSON() ([]byte, error) {
    return json.Marshal(objectid.ObjectId(id).Hex())
}

在结构中使用它代替objectid.ObjectId

type Greeting struct {
    Id Id
    Greeting string
}

现在,当您整理Greeting时,json包会按预期封送Greeting字段,但自Id字段实现json.Marshaler以来,它将是由Id.MarshalJSON编组,输出id.Hex()

您可以通过为Id实施json.Unmarshaler界面来执行相同操作。