返回顶部
首页 > 资讯 > 后端开发 > GO >golang序列化方法是什么
  • 664
分享到

golang序列化方法是什么

2023-07-04 22:07:42 664人浏览 薄情痞子
摘要

这篇文章主要讲解了“golang序列化方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang序列化方法是什么”吧!golang序列化方法有:1、利用Gob包管理gob流,gob

这篇文章主要讲解了“golang序列化方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Golang序列化方法是什么”吧!

golang序列化方法有:1、利用Gob包管理gob流,gob是和类型绑定的,如果发现多了或者少了,会依据顺序填充或者截断。2、利用JSON包,能实现RFC 7159中定义的jsON编码和解码;在序列化的过程中,如果结构体内的成员是小写的,则会出现错误。3、利用Binary包,能实现数字和字节序列之间的简单转换以及varint的编码和解码。4、利用protobuf协议。

编程过程中,我们总是要遇到这样的问题,就是将我们的数据对象要在网络中传输或保存到文件,这就需要对其编码和解码动作。

目前存在很多编码格式:json, XML, Gob, Google Protocol Buffer 等,在Go 语言中,如何对数据进行这样的编码和解码呢?

序列化和反序列化定义

序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。

反过来,把变量从从存储区中重新读取,重新创建该对象,则为反序列化。

在Go语言中,encoding 包就是专门来处理这类序列化的编码和解码的问题。

序列化方式–Gob

gob 包管理 gob 流–编码器(发送器)和解码器(接收器)之间交换的二进制值。一个典型的用途是传输远程过程调用(rpcs)的参数和结果,如 "net/rpc "包中就使用了gobs 流。

他的官网给出了一个示例:

package mainimport ("bytes""encoding/gob""fmt""log")type P struct {X, Y, Z intName    string}type Q struct {X, Y *int32Name string}// This example shows the basic usage of the package: Create an encoder,// transmit some values, receive them with a decoder.func main() {// Initialize the encoder and decoder. NORMally enc and dec would be// bound to network connections and the encoder and decoder would// run in different processes.var network bytes.Buffer        // Stand-in for a network connection  //Buffer是具有Read和Write方法的可变大小的字节缓冲区。enc := gob.NewEncoder(&network) // Will write to network.dec := gob.NewDecoder(&network) // Will read from network.// Encode (send) some values.err := enc.Encode(P{3, 4, 5, "Pythagoras"})if err != nil {log.Fatal("encode error:", err)}err = enc.Encode(P{1782, 1841, 1922, "Treehouse"})if err != nil {log.Fatal("encode error:", err)}// Decode (receive) and print the values.var q Qerr = dec.Decode(&q)if err != nil {log.Fatal("decode error 1:", err)}fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y)err = dec.Decode(&q)if err != nil {log.Fatal("decode error 2:", err)}fmt.Printf("%q: {%d, %d}\n", q.Name, *q.X, *q.Y)}

运行结果是:

"Pythagoras": {3, 4}"Treehouse": {1782, 1841}

个人认为这个例子是真的好。我们看到,结构体PQ 是不同的,我们看到Q 少了一个 Z 变量。

但是,在解码的时候,仍然能解析得出来,这说明,使用 gob 时,是根据类型绑定的,如果发现多了或者少了,会依据顺序填充或者截断。

接下来,我们详情说说怎么编码吧:

1. bytes.Buffer 类型

首先,我们需要定义一个 bytes.Buffer 类型,用来承接需要序列化的结构体,这个类型是这样的:

// A Buffer is a variable-sized buffer of bytes with Read and Write methods.(Buffer是具有Read和Write方法的可变大小的字节缓冲区)// The zero value for Buffer is an empty buffer ready to use.type Buffer struct {buf      []byte // contents are the bytes buf[off : len(buf)]off      int    // read at &buf[off], write at &buf[len(buf)]lastRead readOp // last read operation, so that Unread* can work correctly.}

使用上面的例子,可以看到输出是:

"Pythagoras": {3, 4} ==>{[42 255 129 3 1 1 1 80 1 255 130 0 1 4 1 1 88 1 4 0 1 1 89 1 4 0 1 1 90 1 4 0 1 4 78 97 109 101 1 12 0 0 0 21 255 130 1 6 1 8 1 10 1 10 80 121 116 104 97 103 111 114 97 115 0] 0 0}

可以看到,Buffer 里,是二进制数(一个字节8个bit,最高255)

2. Encode 编码

之后,对需要编码序列化的结构体进行编码:

enc := gob.NewEncoder(&network) // Will write to network.// Encode (send) some values.if err := enc.Encode(P{3, 4, 5, "Pythagoras"}); err != nil {log.Fatal("encode error:", err)}

这里,首先是要获得 *Encoder 对象,获得对象后,利用 *Encoder 对象的方法 Encode 进行编码。

这里,需要注意的是,Encode 如果是网络编程的,其实是可以直接发送消息给对方的,而不必进行 Socket 的send 操作。

比如:在 srever 端有代码:

func main() {l, err := net.Listen("tcp", "127.0.0.1:8000")  //监听端口if err != nil {log.Fatal("net Listen() error is ", err)}p := P{1, 2, 3,"name"}conn, err := l.Accept()if err != nil {log.Fatal("net Accept() error is ", err)}defer func() { _ = conn.Close() }()//参数是conn 时,即可发出enc := gob.NewEncoder(conn)if err = enc.Encode(p); err != nil {  //发生结构体数据log.Fatal("enc Encode() error is ", err)}}

在客户端client有:

func main() {conn,err := net.Dial("tcp","127.0.0.1:8000")if err != nil {log.Fatal("net Dial() error is ", err)}defer func() { _ = conn.Close() }()var q Qdec := gob.NewDecoder(conn)if err = dec.Decode(&q); err != nil {log.Fatal("enc Encode() error is ", err)}fmt.Println(q)}

输出:

{1 2 name}

3. Decode 解码

最后,对其解码的步骤为:

dec := gob.NewDecoder(&network) // Will read from network.if err = dec.Decode(&q);err != nil {log.Fatal("decode error 2:", err)}

序列化方式–json

json 包实现了 RFC 7159 中定义的 JSON 编码和解码。JSON和Go值之间的映射在 Marshal 和 Unmarshal 函数的文档中进行了描述。

示例如下:

type Message struct {QQ      stringAddress string}type Student struct {Id   uint64 `json:"id"` //可以保证json字段按照规定的字段转义,而不是输出 IdAge  uint64 `json:"age"`Data []Message}func main() {m1 := Message{QQ: "123", Address: "beijing"}m2 := Message{QQ: "456", Address: "beijing"}s1 := Student{3, 19, append([]Message{}, m1, m2)}var buf []bytevar err errorif buf, err = json.Marshal(s1); err != nil {log.Fatal("json marshal error:", err)}fmt.Println(string(buf))var s2 Studentif err = json.Unmarshal(buf, &s2); err != nil {log.Fatal("json unmarshal error:", err)}fmt.Println(s2)}//输出://{"id":3,"age":19,"Data":[{"QQ":"123","Address":"beijing"},{"QQ":"456","Address":"beijing"}]}//{3 19 [{123 beijing} {456 beijing}]}

注意

在序列化的过程中,如果结构体内的成员是小写的,则会出现错误。以上两种方式,都会出现这样的结果

我们以 json 序列化为例子,看一下如果是小写的话,会出现什么样的结果:

package mainimport ("encoding/json""fmt""log")type Message struct {qq      stringaddress string}type Student struct {Id   uint64 `json:"id"` //可以保证json字段按照规定的字段转义,而不是输出 IdAge  uint64 `json:"age"`Data []Message}func main() {m1 := Message{"123", "beijing"}m2 := Message{"456", "beijing"}s1 := Student{3, 19, append([]Message{}, m1, m2)}var buf []bytevar err errorif buf, err = json.Marshal(s1); err != nil {log.Fatal("json marshal error:", err)}fmt.Println(string(buf))var s2 Studentif err = json.Unmarshal(buf, &s2); err != nil {log.Fatal("json unmarshal error:", err)}fmt.Println(s2)}

输出:

{"id":3,"age":19,"Data":[{},{}]}{3 19 [{ } { }]}

我们看到,小写的部分将不会被序列化到,也就是说,会是空值。

这个虽然不会报错,但是很明显,不是我们想要看到的结果。

报错:gob: type xxx has no exported fields

我们来看一个会报错的例子:

type Message struct {qq      stringaddress string}type Student struct {Id   uint64 `json:"id"` //可以保证json字段按照规定的字段转义,而不是输出 IdAge  uint64 `json:"age"`Data []Message}func main() {m1 := Message{"123", "beijing"}m2 := Message{"456", "beijing"}s1 := Student{3, 19, append([]Message{}, m1, m2)}var buf bytes.Bufferenc := gob.NewEncoder(&buf)if err := enc.Encode(s1); err != nil {log.Fatal("encode error:", err) //报错}fmt.Println(string(buf.Bytes()))}

这段代码会报错:

2020/12/30 16:44:47 encode error:gob: type main.Message has no exported fields

提醒我们注意,结构体的大小写是很敏感的!!!

序列化方式–Binary

Binary 包实现 数字字节 序列之间的简单转换以及varint的编码和解码。

通过读取和写入固定大小的值来转换数字。 固定大小的值可以是固定大小的算术类型(bool,int8,uint8,int16,float32,complex64等),也可以是仅包含固定大小值的数组或结构体。

示例:

package mainimport ("bytes""encoding/binary""fmt")func main() {buf := new(bytes.Buffer)var pi int64 = 255err := binary.Write(buf, binary.LittleEndian, pi)if err != nil {fmt.Println("binary.Write failed:", err)}fmt.Println( buf.Bytes())}//输出:[255 0 0 0 0 0 0 0]

这里需要注意:如果序列化的类型是 int 类型的话,将会报错:

binary.Write failed: binary.Write: invalid type int

而且,序列化的值是空的。

这是由于,他在前面已经解释清楚了,只能序列化固定大小的类型(bool,int8,uint8,int16,float32,complex64…),或者是结构体和固定大小的数组。

其他序列化方法

当然,go语言还有其他的序列化方法,如 protobuf 协议。

感谢各位的阅读,以上就是“golang序列化方法是什么”的内容了,经过本文的学习后,相信大家对golang序列化方法是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

您可能感兴趣的文档:

--结束END--

本文标题: golang序列化方法是什么

本文链接: https://lsjlt.com/news/347960.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • golang序列化方法是什么
    这篇文章主要讲解了“golang序列化方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“golang序列化方法是什么”吧!golang序列化方法有:1、利用Gob包管理gob流,gob...
    99+
    2023-07-04
  • golang序列化和反序列化的方法是什么
    Go语言中序列化和反序列化可以通过将数据转换为字节流格式来实现,常见方法有“JSON序列化和反序列化”、“XML序列化和反序列化”、“gob序列化和反序列化”和“Protocol Buffers序列化和反序列化”四种:1、使用“json.M...
    99+
    2023-12-18
    golang反序列化 golang序列化 Golang go语言
  • fastjson序列化的方法是什么
    Fastjson提供了多种方式进行序列化,常用的有以下几种方法:1. 使用JSON.toJSONString()方法将对象转化为JS...
    99+
    2023-08-16
    fastjson
  • python protobuf序列化的方法是什么
    在Python中使用protobuf进行序列化的方法是通过调用protobuf库中的SerializeToString()方法来完成...
    99+
    2023-09-12
    python protobuf
  • 初探Golang中的序列化和反序列化方法
    Golang序列化和反序列化的方法初探 序列化和反序列化是计算机科学中常用的概念,指的是将数据结构或对象转换为一种可在网络上传输或存储的格式,以便在需要时能够重新获得原始数据结构或对象。在Golang中,提供...
    99+
    2024-01-29
    Golang 序列化 反序列化
  • redis存放序列化的方法是什么
    在Redis中存放序列化数据有两种常见的方法:1. 使用Redis的String数据类型,并将数据序列化为字符串后存储。常用的序列化...
    99+
    2023-09-05
    redis
  • 实现JSON序列化和反序列化的方法在Golang中
    Golang中JSON序列化和反序列化的实现方式 JSON (JavaScript Object Notation) 是一种常用的数据交换格式,它以文本的形式表示结构化数据。在Golang中,我们可以使用内置...
    99+
    2024-01-29
    Golang 序列化 JSON 实现方式 反序列化
  • spring-session自定义序列化方法是什么
    本篇内容介绍了“spring-session自定义序列化方法是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!spring-session...
    99+
    2023-06-22
  • java内部类序列化的方法是什么
    Java内部类的序列化方法与普通类的序列化方法并没有太大的区别。Java的序列化机制可以将一个对象转换为字节流,然后可以将字节流写入...
    99+
    2023-10-07
    java
  • python序列化json数据的方法是什么
    这篇“python序列化json数据的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“python序列化json数据...
    99+
    2023-06-27
  • Java反序列化对象的方法是什么
    Java中反序列化对象的方法是使用ObjectInputStream类的readObject()方法。可以使用以下步骤来反序列化一个...
    99+
    2023-09-14
    Java
  • Redis序列化与部署的方法是什么
    Redis支持多种序列化方式,包括RDB和AOF。RDB是一种快照方式,将内存中的数据保存到磁盘中,而AOF是一种追加方式,将每次写...
    99+
    2024-04-29
    Redis
  • Redis序列化库的评测方法是什么
    评测Redis序列化库的方法可以基于以下几个指标进行: 性能:评估序列化库在实际使用场景下的性能表现,包括序列化和反序列化的速度...
    99+
    2024-04-29
    Redis
  • java序列化是什么
    序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。(推荐:java视频教程)序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要...
    99+
    2018-09-20
    java
  • java 什么是序列化
    简要解释:序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要被序列化的类实现...
    99+
    2016-08-15
    java入门 java 序列化
  • WCF序列化是什么
    本篇内容介绍了“WCF序列化是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!近期看了大量关于WCF的资料,深入的了解了关于WCF的原理机...
    99+
    2023-06-17
  • redis存储数据序列化的方法是什么
    Redis存储数据时,可以使用以下几种序列化方法:1. 字符串序列化:将数据以字符串的形式进行存储,可以使用Redis提供的字符串数...
    99+
    2023-08-24
    redis
  • Redis序列化数据处理的方法是什么
    Redis序列化数据处理的方法有两种:一种是使用Redis自带的序列化工具,另一种是使用自定义的序列化工具。 使用Redis自带...
    99+
    2024-04-29
    Redis
  • Redis序列化数据传输的方法是什么
    Redis使用一种称为RESP(REdis Serialization Protocol)的二进制协议来序列化数据传输。这种协议是一...
    99+
    2024-04-29
    Redis
  • PHP中的序列化和反序列化是什么
    这篇“PHP中的序列化和反序列化是什么”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“PHP中的序列化和反序列化是什么”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢理解,接下来就让...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作