我的问题与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!"}
答案 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
界面来执行相同操作。