结论
对于值类型的非零值,直接向目标结构赋值,否则跳过不处理;
对于引用类型的非空值,对于slice而言,若原数据len(slice)>0,使用原数据覆盖目标数据;对于map而言,若原数据len(map)>0,遍历原数据为目标数据赋值
反序列化到已赋值的map中的坑
因为反序列化的已赋值的map使用的是赋值的方式,所以对于在初始化时map中已有的数据,而在反序列化map数据中已经被delete掉,经过gob反序列化后是不会将初始化的数据项删除的,需要特别注意下
验证程序如下,感兴趣的可以自己试下,也可以深入看下gob encode/decode的源代码
使用gob序列化反序列化结构的方式
package main
import (
"encoding/gob"
"fmt"
"math/rand"
"os"
"time"
)
type StWithIntBoolMap struct {
Val int
MapData map[int]bool
SliceData []int
}
func main() {
rand.Seed(time.Now().UnixNano())
m := StWithIntBoolMap{
Val: 0,
MapData: make(map[int]bool, 100),
SliceData: []int{10},
}
for i := 0; i < 100; i++ {
if rand.Intn(100) < 50 {
m.MapData[i] = true
}
}
fmt.Println("---------原结构体----------")
fmt.Printf("val值:%d\n结构体map data中数据数量:%d\n,切片中元素数量:%d\n",m.Val,len(m.MapData),len(m.SliceData))
fmt.Println(m.SliceData[0])
// 将结构体内容序列化到文件中
// 首先打开文件,获取文件句柄
f, err := os.OpenFile("ibmap.data", os.O_CREATE|os.O_WRONLY, 0777)
if err != nil {
fmt.Printf("create file error:%s\n", err.Error())
return
}
// 结构体内容写入到文件中
encoder := gob.NewEncoder(f)
err = encoder.Encode(m)
if err != nil {
fmt.Printf("encode data error:%s\n", err.Error())
return
}
// 创建一个新的对象,将文件中的内容反序列化到此结构中
n := StWithIntBoolMap{
Val: 5,
MapData: make(map[int]bool),
SliceData: []int{20},
}
for i := 0; i < 100; i++ { // 注意这里为结构体中的map赋了初始值
n.MapData[i] = true
}
fmt.Println("---------初始化结构体----------")
fmt.Printf("val值:%d\n结构体map data中数据数量:%d\n,切片中元素数量:%d\n",n.Val,len(n.MapData),len(n.SliceData))
fmt.Println(n.SliceData[0])
// 打开文件
file, err := os.OpenFile("ibmap.data", os.O_CREATE, 0777)
if err != nil {
fmt.Printf("open file error:%s", err.Error())
return
}
// 反序列化
decode := gob.NewDecoder(file)
err = decode.Decode(&n)
if err != nil {
fmt.Printf("decode error:%s", err.Error())
return
}
fmt.Println("---------经过反序列化后的结构体----------")
fmt.Printf("val值:%d\n结构体map data中数据数量:%d\n,切片中元素数量:%d\n",n.Val,len(n.MapData),len(n.SliceData))
fmt.Println(n.SliceData[0])
}
// 程序运行结果
/*
---------原结构体----------
val值:0
结构体map data中数据数量:52
,切片中元素数量:1
10
---------初始化结构体----------
val值:5
结构体map data中数据数量:100
,切片中元素数量:1
20
---------经过反序列化后的结构体----------
val值:5
结构体map data中数据数量:100
,切片中元素数量:1
10
*/