Golang:實(shí)現(xiàn)自定義對象的序列化和反序列化
在開發(fā)過程中,我們經(jīng)常需要將對象轉(zhuǎn)換成二進(jìn)制格式進(jìn)行存儲(chǔ)、傳輸?shù)炔僮?。這個(gè)過程被稱為序列化。而將二進(jìn)制數(shù)據(jù)反向轉(zhuǎn)換為對象的過程,則被稱為反序列化。在Golang中,可以使用編碼/解碼庫實(shí)現(xiàn)自定義對象的序列化和反序列化。
1. 序列化:
當(dāng)需要將一個(gè)對象序列化成二進(jìn)制數(shù)據(jù)時(shí),我們需要將該對象的各個(gè)屬性一個(gè)個(gè)轉(zhuǎn)換為對應(yīng)的二進(jìn)制數(shù)據(jù),并將它們按照一定規(guī)則進(jìn)行拼接。因此,序列化需要注意以下幾個(gè)問題:
1.1 序列化方式
在Golang中,我們常用的序列化方式有JSON、XML、protobuf等。下面以JSON為例,介紹序列化的實(shí)現(xiàn)。
1.2 編碼器
在Golang中,可以使用encoding/json中的Marshal函數(shù),將一個(gè)對象序列化為JSON字符串。它的定義如下:
func Marshal(v interface{}) (byte, error)
其中,v代表需要序列化的對象。該函數(shù)的返回值為序列化后的JSON字符串和一個(gè)錯(cuò)誤信息。下面是一個(gè)示例代碼:
type Person struct {
Name string
Age int
}
func main() {
p := Person{Name: "Tom", Age: 18}
b, err := json.Marshal(p)
if err != nil {
fmt.Println("json.Marshal failed:", err)
}
fmt.Println(string(b))
}
輸出結(jié)果為:{"Name":"Tom","Age":18}
1.3 序列化中文字符
在序列化中文字符時(shí),需要使用unicode/utf8包將中文字符轉(zhuǎn)換為Unicode編碼,或者使用第三方庫將序列化后的數(shù)據(jù)進(jìn)行base64編碼。下面是一個(gè)使用base64編碼的示例代碼:
type Person struct {
Name string
Age int
}
func main() {
p := Person{Name: "張三", Age: 18}
b, err := json.Marshal(p)
if err != nil {
fmt.Println("json.Marshal failed:", err)
}
fmt.Println(base64.StdEncoding.EncodeToString(b))
}
輸出結(jié)果為:eyJOb21lIjoi5byg5LiJIiwiQWdlIjoxOH0=
2. 反序列化:
反序列化的過程是將序列化后的二進(jìn)制數(shù)據(jù)解析為一個(gè)對象。在Golang中,可以使用encoding/json中的Unmarshal函數(shù),將JSON字符串反序列化為一個(gè)對象。它的定義如下:
func Unmarshal(data byte, v interface{}) error
其中,data代表需要解析的二進(jìn)制數(shù)據(jù),v代表需要反序列化為的對象。該函數(shù)的返回值為錯(cuò)誤信息。下面是一個(gè)示例代碼:
type Person struct {
Name string
Age int
}
func main() {
s := {"Name":"Tom","Age":18}
var p Person
err := json.Unmarshal(byte(s), &p)
if err != nil {
fmt.Println("json.Unmarshal failed:", err)
}
fmt.Println(p)
}
輸出結(jié)果為:{Tom 18}
需要注意的是,在反序列化時(shí),需要確保JSON字符串的格式與目標(biāo)對象的結(jié)構(gòu)相同,否則會(huì)解析失敗。
3. 自定義對象的序列化和反序列化:
當(dāng)需要序列化自定義對象時(shí),我們需要實(shí)現(xiàn)encoding/json中的Marshaler和Unmarshaler接口。下面是一個(gè)實(shí)現(xiàn)該接口的示例代碼:
type Person struct {
Name string
Age int
}
func (p *Person) MarshalJSON() (byte, error) {
m := mapinterface{}{
"Name": p.Name,
"Age": p.Age,
}
return json.Marshal(m)
}
func (p *Person) UnmarshalJSON(data byte) error {
var m mapinterface{}
err := json.Unmarshal(data, &m)
if err != nil {
return err
}
p.Name = m.(string)
p.Age = int(m.(float64))
return nil
}
func main() {
p := Person{Name: "Tom", Age: 18}
b, err := json.Marshal(p)
if err != nil {
fmt.Println("json.Marshal failed:", err)
}
fmt.Println(string(b))
var p2 Person
err = json.Unmarshal(b, &p2)
if err != nil {
fmt.Println("json.Unmarshal failed:", err)
}
fmt.Println(p2)
}
輸出結(jié)果為:
{"Age":18,"Name":"Tom"}
{Tom 18}
通過實(shí)現(xiàn)Marshaler和Unmarshaler接口,我們可以將自定義對象序列化為JSON字符串,并能夠?qū)崿F(xiàn)JSON字符串的反序列化為自定義對象。
總結(jié):
在Golang中,可以使用encoding/json庫實(shí)現(xiàn)對象的序列化和反序列化。在序列化時(shí),需要注意序列化方式、序列化中文字符等問題;在反序列化時(shí),需要確保JSON字符串的格式與目標(biāo)對象的結(jié)構(gòu)相同,否則會(huì)解析失敗。對于自定義對象的序列化和反序列化,我們需要實(shí)現(xiàn)encoding/json中的Marshaler和Unmarshaler接口。
以上就是IT培訓(xùn)機(jī)構(gòu)千鋒教育提供的相關(guān)內(nèi)容,如果您有web前端培訓(xùn),鴻蒙開發(fā)培訓(xùn),python培訓(xùn),linux培訓(xùn),java培訓(xùn),UI設(shè)計(jì)培訓(xùn)等需求,歡迎隨時(shí)聯(lián)系千鋒教育。