Golang: Gob反序列化到已赋值的结构

结论

        对于值类型的非零值,直接向目标结构赋值,否则跳过不处理;
        对于引用类型的非空值,对于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
*/

你可能感兴趣的:(Go语言学习,golang,gob反序列化)