最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang Gob編碼(gob包的使用詳解)

 更新時(shí)間:2021年05月07日 10:17:04   作者:cqu_jiangzhou  
這篇文章主要介紹了Golang Gob編碼(gob包的使用詳解),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧

gob是Golang包自帶的一個(gè)數(shù)據(jù)結(jié)構(gòu)序列化的編碼/解碼工具。編碼使用Encoder,解碼使用Decoder。一種典型的應(yīng)用場(chǎng)景就是RPC(remote procedure calls)。

gob和json的pack之類的方法一樣,由發(fā)送端使用Encoder對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行編碼。在接收端收到消息之后,接收端使用Decoder將序列化的數(shù)據(jù)變化成本地變量。

基本使用

package main 
import (
	"bytes"
	"encoding/gob"
	"fmt"
)
 
type MsgData struct {
	X, Y, Z int
	Name string
}
var network bytes.Buffer //網(wǎng)絡(luò)傳遞的數(shù)據(jù)載體
func main() {
	err := senMsg()
	if err!=nil {
		fmt.Println("編碼錯(cuò)誤")
		return
	}
	err = revMsg()
	if err!=nil {
		fmt.Println("解碼錯(cuò)誤")
		return
	}
}
 
func senMsg()error {
	fmt.Print("開始執(zhí)行編碼(發(fā)送端)")
 
	enc := gob.NewEncoder(&network)
	sendMsg:=MsgData{3, 4, 5, "jiangzhou"}
	fmt.Println("原始數(shù)據(jù):",sendMsg)
	err := enc.Encode(&sendMsg)
	fmt.Println("傳遞的編碼數(shù)據(jù)為:",network)
	return  err
}
func revMsg()error {
	var revData MsgData
	dec:=gob.NewDecoder(&network)
	err:= dec.Decode(&revData) //傳遞參數(shù)必須為 地址
	fmt.Println("解碼之后的數(shù)據(jù)為:",revData)
	return err
}

Register和RegisterName

1、編碼的數(shù)據(jù)中有空接口類型,傳遞時(shí)賦值的空接口為:基本類型(int、float、string)、切片時(shí),可以不進(jìn)行注冊(cè)。

package main 
import (
	"bytes"
	"encoding/gob"
	"fmt"
)
 
type MsgData struct {
	X, Y, Z int
	Name string
	Msg interface{}
}
var network bytes.Buffer //網(wǎng)絡(luò)傳遞的數(shù)據(jù)載體
func main() {
	err := senMsg()
	if err!=nil {
		fmt.Println("編碼錯(cuò)誤")
		return
	}
	err = revMsg()
	if err!=nil {
		fmt.Println("解碼錯(cuò)誤")
		return
	}
}
 
func senMsg()error {
	fmt.Print("開始執(zhí)行編碼(發(fā)送端)") 
	enc := gob.NewEncoder(&network) 
	s:=make([]string,0)
	s=append(s, "hello")
	//sendMsg:=MsgData{3, 4, 5, "jiangzhou",Msg{10001,"hello"}}
	//sendMsg:=MsgData{3, 4, 5, "jiangzhou",66.66}
	sendMsg:=MsgData{3, 4, 5, "jiangzhou",s}
	fmt.Println("原始數(shù)據(jù):",sendMsg)
	err := enc.Encode(&sendMsg)
	fmt.Println("傳遞的編碼數(shù)據(jù)為:",network)
	return  err
}
func revMsg()error {
	var revData MsgData
	dec:=gob.NewDecoder(&network)
	err:= dec.Decode(&revData) //傳遞參數(shù)必須為 地址
	fmt.Println("解碼之后的數(shù)據(jù)為:",revData)
	return err
}

編碼的數(shù)據(jù)中有空接口類型,傳遞時(shí)賦值的空接口為:map、struct時(shí),必須進(jìn)行注冊(cè)。

package main 
import (
	"bytes"
	"encoding/gob"
	"fmt"
)
 
type MsgData struct {
	X, Y, Z int
	Name string
	Msg interface{}
}
var network bytes.Buffer //網(wǎng)絡(luò)傳遞的數(shù)據(jù)載體
func main() {
	err := senMsg()
	if err!=nil {
		fmt.Println("編碼錯(cuò)誤")
		return
	}
	err = revMsg()
	if err!=nil {
		fmt.Println("解碼錯(cuò)誤")
		return
	}
}
 
func senMsg()error {
	fmt.Print("開始執(zhí)行編碼(發(fā)送端)")
 
	enc := gob.NewEncoder(&network)
 
   m:=make(map[int]string)
	m[10001]="hello"
	m[10002]="jiangzhou"
	sendMsg:=MsgData{3, 4, 5, "jiangzhou",m}
	fmt.Println("原始數(shù)據(jù):",sendMsg)
	err := enc.Encode(&sendMsg)
	fmt.Println("傳遞的編碼數(shù)據(jù)為:",network)
	return  err
}
func revMsg()error {
	var revData MsgData
	dec:=gob.NewDecoder(&network)
	err:= dec.Decode(&revData) //傳遞參數(shù)必須為 地址
	fmt.Println("解碼之后的數(shù)據(jù)為:",revData)
	return err
}

Register和RegisterName解決的主要問題是:當(dāng)編解碼中有一個(gè)字段是interface{}(interface{}的賦值為map、結(jié)構(gòu)體時(shí))的時(shí)候需要對(duì)interface{}的可能產(chǎn)生的類型進(jìn)行注冊(cè)。

正確代碼為:

interface{}的賦值為map時(shí):

package main 
import (
	"bytes"
	"encoding/gob"
	"fmt"
)
 
type MsgData struct {
	X, Y, Z int
	Name string
	Msg interface{}
}
var network bytes.Buffer //網(wǎng)絡(luò)傳遞的數(shù)據(jù)載體
func main() {
	err := senMsg()
	if err!=nil {
		fmt.Println("編碼錯(cuò)誤")
		return
	}
	err = revMsg()
	if err!=nil {
		fmt.Println("解碼錯(cuò)誤")
		return
	}
}
 
func senMsg()error {
	fmt.Print("開始執(zhí)行編碼(發(fā)送端)")
 
	enc := gob.NewEncoder(&network)
 
   m:=make(map[int]string)
	m[10001]="hello"
	m[10002]="jiangzhou"
	gob.Register(map[int]string{}) //TODO:進(jìn)行了注冊(cè)
	sendMsg:=MsgData{3, 4, 5, "jiangzhou",m}
	fmt.Println("原始數(shù)據(jù):",sendMsg)
	err := enc.Encode(&sendMsg)
	fmt.Println("傳遞的編碼數(shù)據(jù)為:",network)
	return  err
}
func revMsg()error {
	var revData MsgData
	dec:=gob.NewDecoder(&network)
	err:= dec.Decode(&revData) //傳遞參數(shù)必須為 地址
	fmt.Println("解碼之后的數(shù)據(jù)為:",revData)
	return err
}

interface{}的賦值為結(jié)構(gòu)體時(shí):

package main 
import (
	"bytes"
	"encoding/gob"
	"fmt"
)
 
type MsgData struct {
	X, Y, Z int
	Name    string
	Msg     interface{}
}
 
var network bytes.Buffer //網(wǎng)絡(luò)傳遞的數(shù)據(jù)載體
func main() {
	err := senMsg()
	if err != nil {
		fmt.Println("編碼錯(cuò)誤",err)
		return
	}
	err = revMsg()
	if err != nil {
		fmt.Println("解碼錯(cuò)誤")
		return
	}
}
 
type Msg struct {
	Id     int
	Detail string
}
 
func senMsg() error {
	fmt.Print("開始執(zhí)行編碼(發(fā)送端)")
	enc := gob.NewEncoder(&network)
	gob.Register(Msg{}) //TODO:進(jìn)行了注冊(cè)
	s:=Msg{10001,"hello jiangzhou"}
	sendMsg := MsgData{3, 4, 5, "jiangzhou", s}
	fmt.Println("原始數(shù)據(jù):", sendMsg)
	err := enc.Encode(&sendMsg)
	fmt.Println("傳遞的編碼數(shù)據(jù)為:", network)
	return err
}
func revMsg() error {
	var revData MsgData
	dec := gob.NewDecoder(&network)
	err := dec.Decode(&revData) //傳遞參數(shù)必須為 地址
	fmt.Println("解碼之后的數(shù)據(jù)為:", revData)
	return err
}

注:特別注意:以上代碼中的結(jié)構(gòu)體Msg對(duì)應(yīng)的成員變量名稱首字母一定要大寫,不然會(huì)出現(xiàn):編碼錯(cuò)誤編碼錯(cuò)誤 gob: type main.Msg has no exported fields

這里使用了

gob.Register(Msg{})

告訴系統(tǒng):所有的Interface是有可能為Msg結(jié)構(gòu)的。

在這個(gè)例子中,如果你注釋了gob.Register, 系統(tǒng)會(huì)報(bào)錯(cuò)。

RegisterName是和Register一樣的效果,只是在Register的同時(shí)也為這個(gè)類型附上一個(gè)別名。

補(bǔ)充:GO語音gob包的系列化和反序列化使用和遇到的錯(cuò)誤

encoding/gob包實(shí)現(xiàn)了高效的序列化,特別是數(shù)據(jù)結(jié)構(gòu)較復(fù)雜的,結(jié)構(gòu)體、數(shù)組和切片都被支持。

package main
 
import (
 "bytes"
 "encoding/gob"
 "fmt"
)
//定義一個(gè)結(jié)構(gòu)體
type Person struct {
 Age int
 Name string
}
 
func main() {
 p1:=Person{
  Age:  18,
  Name: "貪吃的豬",
 }
 //序列化
 //這里是儲(chǔ)存的buffer
 var bufferr bytes.Buffer
 PerEncod:=gob.NewEncoder(&bufferr) //1.創(chuàng)建一個(gè)編碼器
 err:=PerEncod.Encode(&p1) //編碼
 if err != nil {
  fmt.Println("編碼器 解碼錯(cuò)誤",err)
  return
 }
 //現(xiàn)在buffer就是完成儲(chǔ)存序列化的
 fmt.Printf("序列化:buf%x\n",bufferr)
 
 //創(chuàng)建一個(gè)空的結(jié)構(gòu)體來接受
 p2 :=Person{}
 //反序列化
 PerDecod:=gob.NewDecoder(bytes.NewReader(bufferr.Bytes()))//創(chuàng)建一個(gè)反編碼器
 err=PerDecod.Decode(&p2)
 if err != nil {
  fmt.Println("PerDecod.Decode err:",err)
  return
 }
 fmt.Println("反序列化:",p2)
 //fmt.Printf("反序列化數(shù)據(jù):string",p2)
}

系列化和反系列化的常見的錯(cuò)誤

如果是你的結(jié)構(gòu)體的字段是小寫開頭 gob序列化你的結(jié)構(gòu)體的時(shí)候會(huì)找不到字段

如果我把

type Person struct {
    Age int
    Name string
}

改成

type Person struct {
    age int
    name string
}

編碼器 解碼錯(cuò)誤 gob: type main.Person has no exported fields

解決方法就是把字段開頭變成大寫

這個(gè)錯(cuò)誤還有一種可能造成的 你定義的結(jié)構(gòu)里面還有一個(gè)結(jié)構(gòu) 2

這個(gè)結(jié)構(gòu)2的字段全部都是小寫開頭

解決方法就是把字段開頭變成大寫

今天是2019年11月2日 11:32 我的一個(gè)改了半天的bug 終于解決

gob在編譯的時(shí)候 如果你的這個(gè)結(jié)構(gòu)體里面包含另一個(gè)結(jié)構(gòu)體

但是另一個(gè)結(jié)構(gòu)體的字段開頭沒有大寫

gob編譯的時(shí)候是不會(huì)報(bào)錯(cuò),他會(huì)不要沒有大寫的字段,

你反序列化的時(shí)候會(huì)發(fā)現(xiàn)這個(gè)字段是nil 空值

我去你碼的

今天是2019年11月4日,今天新的序列化bug出現(xiàn)了

我生成秘鑰對(duì)然后對(duì)密鑰對(duì)進(jìn)行數(shù)據(jù)序列化然后儲(chǔ)存在文件里面

然后錯(cuò)誤提示,在, gob: type not registered for interface: elliptic.p256Curve

其實(shí)gob是可以序列化全部結(jié)構(gòu),但是它不能序列化interface接口

因?yàn)榻涌诘拇笮∈菬o法定義的

密鑰對(duì)的中的公鑰結(jié)構(gòu)體里面一個(gè)字段elliptic.Curve 他是接口

我們把這個(gè)接口進(jìn)行注冊(cè)就行了

gob提供了一個(gè)函數(shù)可以進(jìn)行注冊(cè)

gob.Register(elliptic.P256())

要gob遇到這個(gè)接口的時(shí)候按照elliptic.P256格式進(jìn)行編譯

然后就解決了~

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Go語言實(shí)現(xiàn)字符串搜索算法Boyer-Moore

    Go語言實(shí)現(xiàn)字符串搜索算法Boyer-Moore

    Boyer-Moore?算法是一種非常高效的字符串搜索算法,被廣泛的應(yīng)用于多種字符串搜索場(chǎng)景,下面我們就來學(xué)習(xí)一下如何利用Go語言實(shí)現(xiàn)這一字符串搜索算法吧
    2023-11-11
  • golang gin框架獲取參數(shù)的操作

    golang gin框架獲取參數(shù)的操作

    這篇文章主要介紹了golang gin框架獲取參數(shù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 使用VSCODE配置GO語言開發(fā)環(huán)境的完整步驟

    使用VSCODE配置GO語言開發(fā)環(huán)境的完整步驟

    Go語言是采用UTF8編碼的,理論上使用任何文本編輯器都能做Go語言開發(fā),大家可以根據(jù)自己的喜好自行選擇,下面這篇文章主要給大家介紹了關(guān)于使用VSCODE配置GO語言開發(fā)環(huán)境的完整步驟,需要的朋友可以參考下
    2022-11-11
  • golang中reflect包的常用方法

    golang中reflect包的常用方法

    Go反射reflect包提供類型和值方法,用于獲取類型信息、訪問字段、調(diào)用方法等,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-07-07
  • GO語言開發(fā)終端命令行小工具改進(jìn)更新

    GO語言開發(fā)終端命令行小工具改進(jìn)更新

    這篇文章主要為大家介紹了GO語言開發(fā)終端命令行小工具的改進(jìn)更新,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-01-01
  • go語言net包rpc遠(yuǎn)程調(diào)用的使用示例

    go語言net包rpc遠(yuǎn)程調(diào)用的使用示例

    本篇文章主要介紹了go語言net包rpc遠(yuǎn)程調(diào)用的使用示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • GO語言類型查詢類型斷言示例解析

    GO語言類型查詢類型斷言示例解析

    這篇文章主要為大家介紹了GO語言類型判斷及類型斷言,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go語言方法集為類型添加方法示例解析

    go語言方法集為類型添加方法示例解析

    這篇文章主要為大家介紹了go語言方法集以及為類型添加方法示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • go語言如何導(dǎo)入和使用包示例詳解

    go語言如何導(dǎo)入和使用包示例詳解

    這篇文章主要為大家介紹了go語言如何導(dǎo)入和使用包示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • GoLang?channel關(guān)閉狀態(tài)相關(guān)操作詳解

    GoLang?channel關(guān)閉狀態(tài)相關(guān)操作詳解

    Channel?和?goroutine?的結(jié)合是?Go?并發(fā)編程的大殺器。而?Channel?的實(shí)際應(yīng)用也經(jīng)常讓人眼前一亮,通過與?select,cancel,timer?等結(jié)合,它能實(shí)現(xiàn)各種各樣的功能。接下來,我們就要介紹GoLang?channel關(guān)閉狀態(tài)相關(guān)操作
    2022-10-10

最新評(píng)論

临清市| 平乐县| 沅江市| 丁青县| 永丰县| 永和县| 诸城市| 津南区| 固始县| 西和县| 晴隆县| 平遥县| 上蔡县| 本溪| 资溪县| 崇明县| 乌什县| 广水市| 六盘水市| 庆安县| 梁山县| 昆明市| 漳州市| 上饶市| 嫩江县| 临武县| 平湖市| 淮阳县| 隆化县| 辽中县| 元氏县| 广宁县| 长阳| 洱源县| 武鸣县| 南陵县| 北川| 四会市| 新平| 古蔺县| 措美县|