接着摸鱼,摸鱼一时爽,一直摸鱼一直爽,接着搞golang
不是所有的数据都可以编码为 JSON 类型,只有验证通过的数据结构才能被编码:
- JSON 对象只支持字符串类型的 key;
- 要编码一个 Go map 类型,map 必须是 map[string]T(T 是 json 包中支持的任何类型)
- Channel,复杂类型和函数类型不能被编码
- 不支持循环数据结构;它将引起序列化进入一个无限循环
go
// 由于golang有个非常恶心的设定,大写才可以被外部包引用,因此我们在json的时候,需要自己定义tag
// 把这个设定的人殴打一百遍的心都有了
type Address struct {
Type string `json:"type"`
City string `json:"city"`
Country string `json:"country"`
}
type VCard struct {
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Addresses []*Address `json:"addresses"`
Remark string `json:"remark"`
}
func main() {
// 声明 && 赋值俩结构体 pa wa是俩指针
pa := &Address{"private", "Aartselaar", "Belgium"}
wa := &Address{"work", "Boom", "Belgium"}
vc := VCard{"Jan", "Kersschot", []*Address{pa, wa}, "none"}
// fmt.Printf("%v: \n", vc) // {Jan Kersschot [0x126d2b80 0x126d2be0] none}:
// JSON format:这一步将结构体转成了json串
js, _ := json.Marshal(vc)
fmt.Printf("JSON format: %s", js)
// using an encoder:写的文件里面
file, _ := os.OpenFile("vcard.json", os.O_CREATE|os.O_WRONLY, 0666)
defer file.Close()
enc := json.NewEncoder(file)
err := enc.Encode(vc)
if err != nil {
log.Println("Error in encoding json")
}
}
json反序列化,使用json.Unmarshal()源码里面有俩参数,数据和目标
编码和解码流
json 包提供
Decoder
和Encoder
类型来支持常用 JSON 数据流读写。NewDecoder()
和
NewEncoder()
函数分别封装了 io.Reader 和 io.Writer 接口。
go
func NewDecoder(r io.Reader) *Decoder
func NewEncoder(w io.Writer) *Encoder
要想把 JSON 直接写入文件,可以使用
json.NewEncoder
初始化文件(或者任何实现 io.Writer 的类型),并调用Encode()
;反过来与其对应的是使用json.NewDecoder
和Decode()
函数:
go
func NewDecoder(r io.Reader) *Decoder
func (dec *Decoder) Decode(v interface{}) error
XML 数据格式
go
// xml.go
package main
import (
"encoding/xml"
"fmt"
"strings"
)
var t, token xml.Token
var err error
func main() {
input := "<Person><FirstName>Laura</FirstName><LastName>Lynn</LastName></Person>"
inputReader := strings.NewReader(input)
p := xml.NewDecoder(inputReader)
// 遍历xml数据格式
for t, err = p.Token(); err == nil; t, err = p.Token() {
switch token := t.(type) {
// 开始节点的名字
case xml.StartElement:
name := token.Name.Local
fmt.Printf("Token name: %s\n", name)
for _, attr := range token.Attr {
attrName := attr.Name.Local
attrValue := attr.Value
fmt.Printf("An attribute is: %s %s\n", attrName, attrValue)
// ...
}
// 节点没了
case xml.EndElement:
fmt.Println("End of token")
// 节点数据
case xml.CharData:
content := string([]byte(token))
fmt.Printf("This is the content: %v\n", content)
// ...
default:
// ...
}
}
}
使用golang内置的Gob
go
// gob1.go
package main
import (
"bytes"
"fmt"
"encoding/gob"
"log"
)
type P struct {
X, Y, Z int
Name string
}
type Q struct {
X, Y *int32
Name string
}
func main() {
// Initialize the encoder and decoder. Normally enc and dec would be
// bound to network connections and the encoder and decoder would
// run in different processes.
var network bytes.Buffer // Stand-in for a network connection
// 写二进制里面
enc := gob.NewEncoder(&network)
// 从二进制里面读取
dec := gob.NewDecoder(&network)
// Encode (send) the value.写数据
err := enc.Encode(P{3, 4, 5, "Pythagoras"})
if err != nil {
log.Fatal("encode error:", err)
}
// Decode (receive) the value.读取数据
var q Q
err = dec.Decode(&q)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Printf("%q: {%d,%d}\n", q.Name, q.X, q.Y)
}