Dr.*_*emo 3 string format serialization json go
package main
import (
"fmt"
"encoding/json"
)
type Ticket struct {
From string
To string
}
func (t Ticket) String() string {
return fmt.Sprintf("%s - %s", t.From, t.To)
}
type Passenger struct {
Name string `json:"Name"`
Tkt Ticket `json:"Ticket"`
}
func main() {
p := Passenger{}
p.Name = "John"
p.Tkt.From = "New York"
p.Tkt.To = "Washington"
buf, _ := json.Marshal(p)
fmt.Println(string(buf))
}
Run Code Online (Sandbox Code Playgroud)
此代码输出:
{"Name":"John","Ticket":{"From":"New York","To":"Washington"}}
Run Code Online (Sandbox Code Playgroud)
但是,使用json.Marshal()
方法(对于复杂结构很简单友好),如何使其输出如下:
{"Name":"John","Ticket":"New York - Washington"}
Run Code Online (Sandbox Code Playgroud)
为了生成 Go 值的 JSON 表示,encoding/json
包检查该值是否实现了json.Marshaler
或encoding.TextMarshaler
接口,如果是,则使用/调用它们(按此顺序)。这是记录在json.Marshal()
:
Marshal 递归地遍历值 v。如果遇到的值实现了 Marshaler 接口并且不是 nil 指针,Marshal 将调用其 MarshalJSON 方法来生成 JSON。如果不存在 MarshalJSON 方法但该值实现了 encoding.TextMarshaler,Marshal 将调用其 MarshalText 方法并将结果编码为 JSON 字符串。
该json/encoding
包不关心的String()
方法。因此,如果您想控制您的值(Ticket
结构)的 JSON 表示/输出,请json.Marshaler
在其上实现(您可以String()
根据自己的喜好调用):
func (t Ticket) MarshalJSON() ([]byte, error) {
return []byte(`"` + t.String() + `"`), nil
}
Run Code Online (Sandbox Code Playgroud)
然后输出将如您所愿:
{"Name":"John","Ticket":"New York - Washington"}
Run Code Online (Sandbox Code Playgroud)
在Go Playground上试一试。
需要注意的一件事:如果string
生产者Ticket.String()
包含引号"
,则输出将变为无效的 JSON,或者更有可能json.Marshal()
返回错误。
为了处理这种转义,最好/最简单的是使用json
包本身:告诉它对以下string
结果进行 JSON 编码Ticket.String()
:
func (t Ticket) MarshalJSON() ([]byte, error) {
return json.Marshal(t.String())
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们像这样测试它:
p.Name = "John"
p.Tkt.From = "New\" York" // CONTAINS QUOTE
p.Tkt.To = "Washington"
buf, err := json.Marshal(p)
fmt.Println(string(buf), err)
Run Code Online (Sandbox Code Playgroud)
输出仍将是有效的 JSON(在Go Playground上尝试):
{"Name":"John","Ticket":"New\" York - Washington"} <nil>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
714 次 |
最近记录: |