浅析Go中序列化与反序列化的基本使用

 更新时间:2023年04月17日 16:47:46   作者:陪我去看海  
序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程,反向过程称为“反序列化”。本文主要介绍了Go中序列化与反序列化的基本使用,需要的可以参考一下

什么是序列化与反序列化

这里引入微软对序列化的解释:

序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存、数据库或文件的过程。 它的主要用途是保存对象的状态,以便能够在需要时重新创建对象。 反向过程称为“反序列化”。

序列化工作原理

将对象序列化为带有数据的流。可以将此流中的对象存储在数据库,文件或者内存中。

在Go中如何序列化一个对象

首先 go 给我提供了便捷的 xml序列化的 API,直接使用即可,我们来看看效果

package main
​
import (
    "encoding/xml"
    "fmt"
)
​
type person struct {
    Name string
    Age  int
}
​
func main() {
    p1 := person{"pkc", 22}
    // xml 序列化
    if data, err := xml.Marshal(p1); err != nil{
        fmt.Println(err)
        return
    } else {
        fmt.Println(data)
        // 将 byte 转为 string
        fmt.Println(string(data))
    }
}

这里我们初始化了一个 struct 对象,将 struct 实例化为 p1,然后使用了 Go 给我们提供的序列化API xml.Marshal,该API是返回两个值 ([]byte, error),将结果进行字符串类型转换后,可以得到结果,是不是看起来很熟悉的感觉呢,就像是标签和标签包裹的内容。

最后的结果:

[60 112 101 114 115 111 110 62 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 60 65 103 101 62 50 50 60 47 65 103 101 62 60 47 112 101 114 115 111 110 62]   
<person><Name>pkc</Name><Age>22</Age></person>

这时候看他,一行显示完,好像不具备可读性。

如何格式化序列化后的数据

这时候 Go 也给我们提供了另一个API,MarshalIndent,该API接收三个参数,分别是,(要序列化的对象,每行的前缀,缩进字符)

// 将 
xml.Marshal(p1)
// 修改为
xml.MarshalIndent(p1, "", " ")

得到结果:

[60 112 101 114 115 111 110 62 10 9 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 10 9 60 65 103 101 62 50 50 60 47 65 103 101 62 10 60 47 112 101 114 115 111 110 62]
<person>
        <Name>pkc</Name>
        <Age>22</Age>
</person>

这时候我们得到了一个 xml结构,但是标签一般都会加上属性,这时候想,如何给标签能加上属性呢

如何给序列化后的xml加上属性

假设:我们要给 Person 标签添加属性 class,我们应该如何做

将代码修改后:

package main
​
import (
    "encoding/xml"
    "fmt"
)
​
// `xml:"xxx,attr"`,xxx 是自定义属性,如果不填,那属性名就是键名:Class
type person struct {
    Class string `xml:"class,attr"`
    Name string
    Age  int
}
​
func main() {
    p1 := person{"container", "pkc", 22}
    // xml 序列化
    if data, err := xml.MarshalIndent(p1, "", " "); err != nil{
        fmt.Println(err)
        return
    } else {
        fmt.Println(data)
        // 将 byte 转为 string
        fmt.Println(string(data))
    }
}

这里使用了Go中struct中的field tag语法 是声明类型之后的注解,这样就成功给标签添加上属性以及值了

结果:

[60 112 101 114 115 111 110 32 99 108 97 115 115 61 34 99 111 110 116 97 105 110 101 114 34 62 10 9 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 10 9 60 65 103 101 62 50 50 60 47 65 103 101 62 10 60 47 112 101 114 115 111 110 62]        
<person class="container">
        <Name>pkc</Name>
        <Age>22</Age>
</person>

如何将xml反序列化为一个对象

说完了序列化,那么我们拿着序列化之后的数据,如何反序列化变成我们想要的结构呢

这里Go也是提供了API,Unmarshal,该API接收两个参数,第一个([]byte,接收反序列化后的对象),代码修改后

package main
​
import (
    "encoding/xml"
    "fmt"
)
​
type person struct {
    Class string `xml:"class,attr"`
    Name string
    Age  int
}
​
func main() {
    var data []byte
    var err error
​
    p1 := person{"container", "pkc", 22}
    // xml 序列化
    if data, err = xml.MarshalIndent(p1, "", "  "); err != nil{
        fmt.Println(err)
        return
    }
    fmt.Println(data)
    // 将 byte 转为 string
    fmt.Println(string(data))
    fmt.Println()
​
    // 创建示例接收反序列化的对象
    p2 := new(person)
    if err = xml.Unmarshal(data, p2); err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("反序列化后:%v", p2)
}

结果:

[60 112 101 114 115 111 110 32 99 108 97 115 115 61 34 99 111 110 116 97 105 110 101 114 34 62 10 9 60 78 97 109 101 62 112 107 99 60 47 78 97 109 101 62 10 9 60 65 103 101 62 50 50 60 47 65 103 101 62 10 60 47 112 101 114 115 111 110 62]        
<person class="container">
        <Name>pkc</Name>
        <Age>22</Age>
</person>

反序列化后:&{container pkc 22}

到此这篇关于浅析Go中序列化与反序列化的基本使用的文章就介绍到这了,更多相关Go序列化 反序列化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • GoLang内存模型详细讲解

    GoLang内存模型详细讲解

    go官方介绍go内存模型的时候说:探究在什么条件下,goroutine 在读取一个变量的值的时,能够看到其它 goroutine 对这个变量进行的写的结果,Go内存模型规定了一些条件,在这些条件下,在一个goroutine中读取变量返回的值能够确保是另一个goroutine中对该变量写入的值
    2022-12-12
  • 深入理解go sync.Once的具体使用

    深入理解go sync.Once的具体使用

    在很多情况下,我们可能需要控制某一段代码只执行一次,go 为我们提供了 sync.Once 对象,它保证了某个动作只被执行一次,本文主要介绍了深入理解go sync.Once的具体使用,感兴趣的可以了解一下
    2024-01-01
  • 一文带你使用golang手撸一个websocket中间件

    一文带你使用golang手撸一个websocket中间件

    这篇文章主要为大家详细介绍了如何使用golang手撸一个websocket中间件,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以参考一下
    2023-12-12
  • Bililive-go 实现直播自动监控录制功能

    Bililive-go 实现直播自动监控录制功能

    最近有直播录制的需求,但是自己手动录制太麻烦繁琐,于是用了开源项目Bililive-go进行全自动监控录制,对Bililive-go 直播自动监控录制实现思路感兴趣的朋友,一起看看吧
    2024-03-03
  • golang context接口类型方法介绍

    golang context接口类型方法介绍

    这篇文章主要为大家介绍了golang context接口类型方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 使用Go http重试请求的示例

    使用Go http重试请求的示例

    开发中对于http请求是经常遇到,一般可能网络延迟或接口返回超时,这篇文章主要介绍了使用Go http重试请求的示例,需要的朋友可以参考下
    2022-08-08
  • Go实现文件上传和下载

    Go实现文件上传和下载

    这篇文章主要为大家详细介绍了Go实现文件上传和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • Golang中对json的优雅处理方式

    Golang中对json的优雅处理方式

    这篇文章主要给大家介绍了关于Golang中对json的优雅处理方式,解析JSON在golang中很麻烦,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • Go sync WaitGroup使用深入理解

    Go sync WaitGroup使用深入理解

    这篇文章主要为大家介绍了Go sync WaitGroup使用深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • 深入探索Go语言中unsafe包的使用

    深入探索Go语言中unsafe包的使用

    Go语言的unsafe包被誉为黑科技,它为Go语言提供了底层访问和操控内存的能力,本文将深入探讨Go语言中unsafe包的使用方法和注意事项,需要的可以参考一下
    2023-04-04

最新评论