淺析Go中序列化與反序列化的基本使用
什么是序列化與反序列化
這里引入微軟對序列化的解釋:
序列化是指將對象轉(zhuǎn)換成字節(jié)流,從而存儲對象或?qū)ο髠鬏數(shù)絻?nèi)存、數(shù)據(jù)庫或文件的過程。 它的主要用途是保存對象的狀態(tài),以便能夠在需要時重新創(chuàng)建對象。 反向過程稱為“反序列化”。
序列化工作原理
將對象序列化為帶有數(shù)據(jù)的流。可以將此流中的對象存儲在數(shù)據(jù)庫,文件或者內(nèi)存中。
在Go中如何序列化一個對象
首先 go
給我提供了便捷的 xml序列化的 API,直接使用即可,我們來看看效果
package main ? import ( "encoding/xml" "fmt" ) ? type person struct { Name string Age int } ? func main() { p1 := person{"pkc", 22} // xml 序列化 if data, err := xml.Marshal(p1); err != nil{ fmt.Println(err) return } else { fmt.Println(data) // 將 byte 轉(zhuǎn)為 string fmt.Println(string(data)) } }
這里我們初始化了一個 struct 對象
,將 struct
實例化為 p1
,然后使用了 Go
給我們提供的序列化API xml.Marshal
,該API是返回兩個值 ([]byte, error)
,將結(jié)果進行字符串類型轉(zhuǎn)換后,可以得到結(jié)果,是不是看起來很熟悉的感覺呢,就像是標簽和標簽包裹的內(nèi)容。
最后的結(jié)果:
[60 112 101 114 115 111 110 62 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 60 65 103 101 62 50 50 60 47 65 103 101 62 60 47 112 101 114 115 111 110 62]
<person><Name>pkc</Name><Age>22</Age></person>
這時候看他,一行顯示完,好像不具備可讀性。
如何格式化序列化后的數(shù)據(jù)
這時候 Go
也給我們提供了另一個API,MarshalIndent
,該API接收三個參數(shù),分別是,(要序列化的對象,每行的前綴,縮進字符)
// 將 xml.Marshal(p1) // 修改為 xml.MarshalIndent(p1, "", " ")
得到結(jié)果:
[60 112 101 114 115 111 110 62 10 9 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 10 9 60 65 103 101 62 50 50 60 47 65 103 101 62 10 60 47 112 101 114 115 111 110 62]
<person>
<Name>pkc</Name>
<Age>22</Age>
</person>
這時候我們得到了一個 xml
結(jié)構(gòu),但是標簽一般都會加上屬性,這時候想,如何給標簽能加上屬性呢
如何給序列化后的xml加上屬性
假設:我們要給 Person 標簽添加屬性 class,我們應該如何做
將代碼修改后:
package main ? import ( "encoding/xml" "fmt" ) ? // `xml:"xxx,attr"`,xxx 是自定義屬性,如果不填,那屬性名就是鍵名:Class type person struct { Class string `xml:"class,attr"` Name string Age int } ? func main() { p1 := person{"container", "pkc", 22} // xml 序列化 if data, err := xml.MarshalIndent(p1, "", " "); err != nil{ fmt.Println(err) return } else { fmt.Println(data) // 將 byte 轉(zhuǎn)為 string fmt.Println(string(data)) } }
這里使用了Go中struct中的field tag語法
是聲明類型之后的注解,這樣就成功給標簽添加上屬性以及值了
結(jié)果:
[60 112 101 114 115 111 110 32 99 108 97 115 115 61 34 99 111 110 116 97 105 110 101 114 34 62 10 9 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 10 9 60 65 103 101 62 50 50 60 47 65 103 101 62 10 60 47 112 101 114 115 111 110 62]
<person class="container">
<Name>pkc</Name>
<Age>22</Age>
</person>
如何將xml反序列化為一個對象
說完了序列化,那么我們拿著序列化之后的數(shù)據(jù),如何反序列化變成我們想要的結(jié)構(gòu)呢
這里Go
也是提供了API,Unmarshal
,該API接收兩個參數(shù),第一個([]byte,接收反序列化后的對象),代碼修改后
package main ? import ( "encoding/xml" "fmt" ) ? type person struct { Class string `xml:"class,attr"` Name string Age int } ? func main() { var data []byte var err error ? p1 := person{"container", "pkc", 22} // xml 序列化 if data, err = xml.MarshalIndent(p1, "", " "); err != nil{ fmt.Println(err) return } fmt.Println(data) // 將 byte 轉(zhuǎn)為 string fmt.Println(string(data)) fmt.Println() ? // 創(chuàng)建示例接收反序列化的對象 p2 := new(person) if err = xml.Unmarshal(data, p2); err != nil { fmt.Println(err) return } fmt.Printf("反序列化后:%v", p2) }
結(jié)果:
[60 112 101 114 115 111 110 32 99 108 97 115 115 61 34 99 111 110 116 97 105 110 101 114 34 62 10 9 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 10 9 60 65 103 101 62 50 50 60 47 65 103 101 62 10 60 47 112 101 114 115 111 110 62]
<person class="container">
<Name>pkc</Name>
<Age>22</Age>
</person>
?
反序列化后:&{container pkc 22}
到此這篇關于淺析Go中序列化與反序列化的基本使用的文章就介紹到這了,更多相關Go序列化 反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Go語言字典(map)用法實例分析【創(chuàng)建,填充,遍歷,查找,修改,刪除】
這篇文章主要介紹了Go語言字典(map)用法,結(jié)合實例形式較為詳細的分析了Go語言字典的創(chuàng)建、填充、遍歷、查找、修改、刪除等操作相關實現(xiàn)技巧,需要的朋友可以參考下2017-02-02