登录  /  注册
首页 > 后端开发 > Golang > 正文

记录Go语言采坑记录gob序列化坑

藏色散人
发布: 2021-03-26 17:18:04
转载
2543人浏览过

下面由golang教程栏目给大家分享go语言采坑记录gob序列化坑,希望对需要的朋友有所帮助!

package mainimport (
	"bytes"
	"encoding/gob"
	"fmt"
	"log"
	"os")func main() {
	/// 序列化编码&写入文件开始 ///
	// 实例化一个学生对象s1
	s1 := &Student{id: 1, name: "jack ma", age: 2, cash: 43242334.35}

	// 实例化一个gob编码对象,并对s1学生对象进行编码
	var buf bytes.Buffer
	encoder := gob.NewEncoder(&buf)
	error2Log("Encode: ", encoder.Encode(s1))

	// 输出序列化后的类容
	fmt.Printf("Serialized: %x\n", buf.Bytes())

	// 创建data.data文件,存放序列化数据
	fs, err := os.Create("./data.data")
	error2Log("Creat File: ", err)
	// 写入数据,并打印写入数据长度
	wlen, err := fs.Write(buf.Bytes())
	error2Log("Write file: ", err)
	fmt.Println("Wirte bytes:", wlen)
	fs.Close()

	/// 序列化编码&写入文件结束 ///

	/// 读入文件&反序列化编码开始 ///

	// 从文件打开写入的序列化数据
	fs, err = os.Open("./data.data")
	error2Log("Open file: ", err)
	// 获取文件信息接口
	finfo, err := fs.Stat()
	error2Log("Get fileinfo: ", err)
	// 根据文件大小创建字节数组,然后将文件中数据读入到字节数组中,并打印读入数据长度
	readBuf := make([]byte, finfo.Size())
	rlen, err := fs.Read(readBuf)
	error2Log("Read file: ", err)
	fmt.Println("Read bytes:", rlen)
	fs.Close()

	// 实例化一个用于接收反序列化数据的学生对象
	s2 := new(Student)

	// 实例化一个gob解码对象
	decoder := gob.NewDecoder(bytes.NewReader(readBuf))
	// 将数据解码到学生对象s2
	error2Log("Decode: ", decoder.Decode(s2))
	// 将反序列化后的数据,s2学生对象打印出来
	fmt.Println("Unserialized:", s2)

	/// 读入文件&反序列化编码结束 ///}func error2Log(m string, e error) {
	if e != nil {
		log.Fatal(m, e)
	}}// Student 学生对象type Student struct {
	id   uint64
	name string
	age  uint
	cash float64}
登录后复制
登录后复制

编译后运行结构如下:

2019/04/17 15:07:46 Encode: gob: type main.Student has no exported fields
登录后复制
登录后复制

害的我郁闷了一个多小时。查询了一些信息,比如:

https://github.com/golang/go/issues/5819
但是这不是我的需要的问题解决方法,我就想将一个结构体对象写到文件中去,也没打算嵌入结构体呀。
后来突然灵光一闪,我犯了个超级低级错误:

type Student struct {
	id   uint64
	name string
	age  uint
	cash float64}
登录后复制
登录后复制

尼玛… 结构体成员(golang叫字段)小写…,突然想起来关于包级的变量名和函数名,小写相当于private… 难道是这样?
马上改了:

type Student struct {
	ID   uint64
	Name string
	Age  uint
	Cash float64}
登录后复制
登录后复制

14行那里的实例化s1改成:

s1 := &Student{ID: 1, Name: "jack ma", Age: 2, Cash: 43242334.35}
登录后复制
登录后复制

然后编译运行结构终于正确:

Serialized: 36ff810301010753747564656e7401ff820001040102494401060001044e616d65010c00010341676501060001044361736801080000001aff82010101076a61636b206d61010201f8cdccccf29a9e844100
Wirte bytes: 82
Read bytes: 82
Unserialized: &{1 jack ma 2 4.324233435e+07}
登录后复制

这相当于回过头来看,在golang中没有养成的代码习惯。
所以今后写结构体的时候,得养成好习惯:字段名应该使用首字母大写。(555555555555555~)

package mainimport (
	"bytes"
	"encoding/gob"
	"fmt"
	"log"
	"os")func main() {
	/// 序列化编码&写入文件开始 ///
	// 实例化一个学生对象s1
	s1 := &Student{id: 1, name: "jack ma", age: 2, cash: 43242334.35}

	// 实例化一个gob编码对象,并对s1学生对象进行编码
	var buf bytes.Buffer
	encoder := gob.NewEncoder(&buf)
	error2Log("Encode: ", encoder.Encode(s1))

	// 输出序列化后的类容
	fmt.Printf("Serialized: %x\n", buf.Bytes())

	// 创建data.data文件,存放序列化数据
	fs, err := os.Create("./data.data")
	error2Log("Creat File: ", err)
	// 写入数据,并打印写入数据长度
	wlen, err := fs.Write(buf.Bytes())
	error2Log("Write file: ", err)
	fmt.Println("Wirte bytes:", wlen)
	fs.Close()

	/// 序列化编码&写入文件结束 ///

	/// 读入文件&反序列化编码开始 ///

	// 从文件打开写入的序列化数据
	fs, err = os.Open("./data.data")
	error2Log("Open file: ", err)
	// 获取文件信息接口
	finfo, err := fs.Stat()
	error2Log("Get fileinfo: ", err)
	// 根据文件大小创建字节数组,然后将文件中数据读入到字节数组中,并打印读入数据长度
	readBuf := make([]byte, finfo.Size())
	rlen, err := fs.Read(readBuf)
	error2Log("Read file: ", err)
	fmt.Println("Read bytes:", rlen)
	fs.Close()

	// 实例化一个用于接收反序列化数据的学生对象
	s2 := new(Student)

	// 实例化一个gob解码对象
	decoder := gob.NewDecoder(bytes.NewReader(readBuf))
	// 将数据解码到学生对象s2
	error2Log("Decode: ", decoder.Decode(s2))
	// 将反序列化后的数据,s2学生对象打印出来
	fmt.Println("Unserialized:", s2)

	/// 读入文件&反序列化编码结束 ///}func error2Log(m string, e error) {
	if e != nil {
		log.Fatal(m, e)
	}}// Student 学生对象type Student struct {
	id   uint64
	name string
	age  uint
	cash float64}
登录后复制
登录后复制

编译后运行结构如下:

2019/04/17 15:07:46 Encode: gob: type main.Student has no exported fields
登录后复制
登录后复制

害的我郁闷了一个多小时。查询了一些信息,比如:
https://github.com/golang/go/issues/5819
但是这不是我的需要的问题解决方法,我就想将一个结构体对象写到文件中去,也没打算嵌入结构体呀。
后来突然灵光一闪,我犯了个超级低级错误:

type Student struct {
	id   uint64
	name string
	age  uint
	cash float64}
登录后复制
登录后复制

尼玛… 结构体成员(golang叫字段)小写…,突然想起来关于包级的变量名和函数名,小写相当于private… 难道是这样?
马上改了:

type Student struct {
	ID   uint64
	Name string
	Age  uint
	Cash float64}
登录后复制
登录后复制

14行那里的实例化s1改成:

s1 := &Student{ID: 1, Name: "jack ma", Age: 2, Cash: 43242334.35}
登录后复制
登录后复制

然后编译运行结构终于正确:

Serialized: 36ff810301010753747564656e7401ff820001040102494401060001044e616d65010c00010341676501060001044361736801080000001aff82010101076a61636b206d61010201f8cdccccf29a9e844100
Wirte bytes: 82
Read bytes: 82
Unserialized: &{1 jack ma 2 4.324233435e+07}
登录后复制

这相当于回过头来看,在golang中没有养成的代码习惯。
所以今后写结构体的时候,得养成好习惯:字段名应该使用首字母大写。(555555555555555~)

以上就是记录Go语言采坑记录gob序列化坑的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
相关标签:
来源:csdn网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号