1.Json.Marshal会有什么问题?
下边示例是将json序列化成bytes,然后把bytes反序列化到匹配的结构体。
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
}
func main() {
in := `{"firstName":"John","lastName":"Dow"}`
bytes, err := json.Marshal(in)
if err != nil {
panic(err)
}
var p Person
err = json.Unmarshal(bytes, &p)
if err != nil {
panic(err)
}
fmt.Printf("%+v", p)
}
运行程序发现,程序panic了。
panic: json: cannot unmarshal string into Go value of type main.Person
goroutine 1 [running]:
main.main()
/tmp/sandbox071126523/prog.go:24 +0x1e9
Person
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
}
func main() {
bytes, err := json.Marshal(Person{
FirstName: "John",
LastName: "Dow",
})
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
输出的结果如下:
{"firstName":"John","lastName":"Dow"}
序列化后的结构体,跟我们的json字符串是一样的。
2.原因是什么?
我们比较一下序列化json字符串以及结构体序列化的结果。
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
}
func main() {
bytes, err := json.Marshal(Person{
FirstName: "John",
LastName: "Dow",
})
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
in := `{"firstName":"John","lastName":"Dow"}`
bytes, err = json.Marshal(in)
if err != nil {
panic(err)
}
fmt.Println(string(bytes))
}
输出结果如下:
{"firstName":"John","lastName":"Dow"}
"{\"firstName\":\"John\",\"lastName\":\"Dow\"}"
你能看到转义的双引号么?这是问题的症结所在,json.Marshal在对字符串进行序列化的时候,会对字符串进行转义。
3.如何避免被转义
RawMessagejson.RawMessage
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
}
func main() {
in := `{"firstName":"John","lastName":"Dow"}`
rawIn := json.RawMessage(in)
bytes, err := rawIn.MarshalJSON()
if err != nil {
panic(err)
}
var p Person
err = json.Unmarshal(bytes, &p)
if err != nil {
panic(err)
}
fmt.Printf("%+v", p)
}
输出结果如下:
{FirstName:John LastName:Dow}
是正确的结果。
4.有没有更简单的方式
json.RawMessage[]byte[]byte
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
}
func main() {
in := `{"firstName":"John","lastName":"Dow"}`
bytes := []byte(in)
var p Person
err := json.Unmarshal(bytes, &p)
if err != nil {
panic(err)
}
fmt.Printf("%+v", p)
}
输出结果是一样的:
{FirstName:John LastName:Dow}