天天看點

Go 對象序列化

在程式運作的過程中,所有的變量都是在記憶體中。可以随時修改變量,但是一旦程式結束,變量所占用的記憶體就會被作業系統全部回收。如果你想在程式退出後,仍然可以通路資料,就需要使用序列化,将對象的目前狀态寫入到臨時或持久性存儲區。以後,可以通過從存儲區中讀取或反序列化對象的狀态,重新建立該對象。

把變量從記憶體中變成可存儲或傳輸的過程稱之為序列化,序列化之後,就可以把序列化後的内容寫入到磁盤,或者通過網絡傳輸到别的機器上。反過來,把變量内容從序列化的對象重新讀到記憶體裡稱之為反序列化。

序列化的目的

  1. 以某種存儲形式使自定義對象持久化
  2. 将對象從一個地方傳遞到另一個地方
  3. 使程式更具維護性

序列化為json格式

如果要在不同的程式設計語言之間傳遞對象,就必須把對象序列化為标準格式,比如

XML

,但通常使用

JSON

格式。因為JSON表示出來就是一個字元串,可以被所有語言讀取,且讀取速度比XML更快,非常友善。

Go

内置的标準包

encoding/json

下面有

Go

對象到

Json

格式的轉化,官方有關介紹可以戳https://golang.org/doc/articles/json_and_go.html。

json.Marshal

func Marshal(v interface{}) ([]byte, error) {
    //...
}
           

Marshal

方法會将Go對象序列化為JSON字元串,而在Go語言底層,一個字元串值即一個包含了若幹個位元組的序列。位元組序列在Go中用

[]byte

類型表示,即一個由8位二進制數表示的無符号整數的切片(

[]uint8

)。

示例

package main

import (
    "fmt"
    "encoding/json"
)

type Info struct {
    Name string
    Age  int
    Sex  string
}

func main() {
    infos := []Info{
        {
			Name: "Sophia",
			Age:  23,
			Sex:  "female",
		},
		{
			Name: "Benjie",
			Age:  24,
			Sex:  "male",
		},
    }
    data, err := json.Marshal(infos)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(data)
    fmt.Println(string(data))

    /*
    [91 123 34 78 97 109 101 34 58 34 83 111 112 104 105 97 34 44 34 65 103 101 34 58 50 51 44 34 83 101 120 34 58 34 102 101 109 9
7 108 101 34 125 44 123 34 78 97 109 101 34 58 34 66 101 110 106 105 101 34 44 34 65 103 101 34 58 50 52 44 34 83 101 120 34 58
 34 109 97 108 101 34 125 93] 
    [{"Name":"Sophia","Age":23,"Sex":"female"},{"Name":"Benjie","Age":24,"Sex":"male"}]
    */
}
           

反序列化json資料為Go對象

json.Unmarshal

func Unmarshal(data []byte, v interface{}) error {
    //...
}
           

Unmarshal

函數會解析JSON編碼的資料,然後将結果儲存到v中。如果傳入的參數v的值為nil,或者類型不是指針,那麼函數會傳回一個錯誤。

如果解析的内容字面上為空,那麼

Unmarshal

會将結果指向

nil

。否則,會将結果反序列化到v指向的對象中。為了将JSON反序列化到Go結構體,

Unmarshal

會将Json對象中的key和結構體中的key(也可以是結構體标簽)進行比對,而且對大小寫不敏感。

示例

package main

import (
	"fmt"
	"encoding/json"
)

type Info struct {
	Name string
	Age  int
	Sex  string
}

func main() {
	var str = []byte(`[
                {"name":"Sophia","age":23,"sex":"female"},
                {"name":"Benjie","age":32,"sex":"male"}
                    ]`)
	var info []Info
	if err := json.Unmarshal(str, &info); err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(info)
    //列印結果:[{Sophia 23 female} {Benjie 32 male}]
}
           

參考文章

  1. 序列化