首頁 > 後端開發 > Golang > 主體

記錄Go語言採坑記錄gob序列化坑

藏色散人
發布: 2021-03-26 17:18:28
轉載
2787 人瀏覽過

下面由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
登入後複製
登入後複製

##

type Student struct {
	id   uint64
	name string
	age  uint
	cash float64}
登入後複製
登入後複製

編譯後運行結構如下:

type Student struct {
	ID   uint64
	Name string
	Age  uint
	Cash float64}
登入後複製
登入後複製

#傷害的我鬱悶了一個多小時。查詢了一些信息,例如:

https://github.com/golang/go/issues/5819
但這不是我的需要的問題解決方法,我就想將一個結構體物件寫到文件中去,也沒打算嵌入結構體呀。

後來突然靈光一閃,我犯了個超級低階錯誤:

s1 := &Student{ID: 1, Name: "jack ma", Age: 2, Cash: 43242334.35}
登入後複製
登入後複製

尼瑪… 結構體成員(golang叫字段)小寫…,突然想起來關於包級的變數名稱和函數名,小寫相當於private… 難道是這樣?

馬上改了:

Serialized: 36ff810301010753747564656e7401ff820001040102494401060001044e616d65010c00010341676501060001044361736801080000001aff82010101076a61636b206d61010201f8cdccccf29a9e844100
Wirte bytes: 82
Read bytes: 82
Unserialized: &{1 jack ma 2 4.324233435e+07}
登入後複製

14行那裡的實例化s1改成:

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
登入後複製
登入後複製
這相當於回頭來看,在golang中沒有養成的程式碼習慣。 所以今後寫結構體的時候,得養成好習慣:字段名應該要用首字母大寫。 (555555555555555~)


type Student struct {
	id   uint64
	name string
	age  uint
	cash float64}
登入後複製
登入後複製

編譯後運行結構如下:
type Student struct {
	ID   uint64
	Name string
	Age  uint
	Cash float64}
登入後複製
登入後複製

害的我鬱悶了一個多小時。查詢了一些信息,例如:

https://github.com/golang/go/issues/5819
但這不是我的需要的問題解決方法,我就想將一個結構體物件寫到文件中去,也沒打算嵌入結構體呀。

後來突然靈光一閃,我犯了個超級低階錯誤:

s1 := &Student{ID: 1, Name: "jack ma", Age: 2, Cash: 43242334.35}
登入後複製
登入後複製

尼瑪… 結構體成員(golang叫字段)小寫…,突然想起來關於包級的變數名稱和函數名,小寫相當於private… 難道是這樣?

馬上改了:

Serialized: 36ff810301010753747564656e7401ff820001040102494401060001044e616d65010c00010341676501060001044361736801080000001aff82010101076a61636b206d61010201f8cdccccf29a9e844100
Wirte bytes: 82
Read bytes: 82
Unserialized: &{1 jack ma 2 4.324233435e+07}
登入後複製

14行那裡的實例化s1改成:
rrreee

然後編譯運行結構終於正確:###rrreee###這相當於回頭來看,在golang中沒有養成的程式碼習慣。 ### 所以今後寫結構體的時候,得養成好習慣:字段名應該要用首字母大寫。 (555555555555555~)###

以上是記錄Go語言採坑記錄gob序列化坑的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!