返回顶部
首页 > 资讯 > 后端开发 > GO >Golang Protocol Buffer案例详解
  • 196
分享到

Golang Protocol Buffer案例详解

2024-04-02 19:04:59 196人浏览 独家记忆
摘要

golang Protocol Buffer教程 本文介绍如何在Go应用中利用Protocol Buffer数据格式。主要包括什么是Protocol Buffer数据格式,其超越传统

golang Protocol Buffer教程

本文介绍如何在Go应用中利用Protocol Buffer数据格式。主要包括什么是Protocol Buffer数据格式,其超越传统数据格式XML或JSON的优势是什么。

1. Protocol Buffer数据格式

Protocol Buffer,本质就是一种数据格式,和jsON或XML一样,不同的语言用于结构化数据序列化或反序列化。该数据格式的优势是较xml或json更小,源于Google。假如我们有一个对象,我们用三种数据结构进行表示:


<person>
  <name>Elliot</name>
  <age>24</age>
</person>

使用json表示占用空间更小:


{
  "name": "Elliot",
  "age": 24
}

如果使用protocol buffer格式表示:


[10 6 69 108 108 105 111 116 16 24]

如果您仔细观察上面编码可能会看到,从数组位置2开始名字elliot被拼出来,e = 69, l = 108等等。后面是年龄的字节表示,24岁。

不过编码格式内容比我们看到的要多,下面会更详细地解释,如果您愿意可看其官方文档。

现在这个示例数据,Json和 Protocol Buffer格式几乎没有太大差别,但当遇到数据量很大场景时,差别就体现出来了。

2. 简单示例

首先下载必要的依赖:


go get GitHub.com/golang/protobuf
go get github.com/golang/protobuf/proto

下载完成后,确保能够在命令行中可以运行 protoc 命令。下面我们定义 protobuf 结构,这里定义上面用来对比不同数据格式之间差异的person 对象。

首先指定我们使用的语法格式,这里使用 proto3,然后指定存放的包名。最后定义对象,Peson类型的消息及其包括的字段 name 和 age。

person.proto结构定义如下:


syntax="proto3";

package main;

message Person {
      string name = 1;
      int32 age = 2;
}

然后在该文件的路径下运行下面命令:


protoc --go_out=. *.proto

即在当前目录下 生成所有扩展名为 proto文件的 .pb.go 文件。
现在我们定义Person类型对象使用 protobuf格式进行序列化。代码如下;


import (
    "fmt"
    "log"

    "github.com/golang/protobuf/proto"
)

func main() {
  elliot := &Person{
    Name: "Elliot",
    Age:  24,
  }

  data, err := proto.Marshal(elliot)
  if err != nil {
    log.Fatal("marshaling error: ", err)
  }

  // 打印原始的protobuf序列化对象
  fmt.Println(data)


  // 反序列化进行验证
  newElliot := &Person{}
  err = proto.Unmarshal(data, newElliot)
  if err != nil {
    log.Fatal("unmarshaling error: ", err)
  }

  // 打印 `newElliot` 对象进行验证
  fmt.Println(newElliot.GetAge())
  fmt.Println(newElliot.GetName())

}

使用go run 命令运行,需要在main.go 后面传入 person.pb.go,命令如下:


go run main.go test.pb.go

在ide环境中可以直接运行。输出结果如下:


[10 6 69 108 108 105 111 116 16 24]
name:"Elliot" age:24

3. 嵌套示例

我们已经完成了一个非常简单的示例,但现实中消息格式通常会遇到多个嵌套字段,下面增加嵌套类型字段。

我们仍然使用前面 Person 类型,仅增加社交网络的粉丝字段。SocialFollowers的消息类型如下:


syntax="proto3";

package main;

message SocialFollowers {
  int32 youtube = 1;
  int32 twitter = 2;
}

message Person {
  string name = 1;
  int32 age = 2;
  SocialFollowers socialFollowers = 3;
}

因为Person 类型已经被修改了,需要重新运行 protoc 命令:


protoc --go_out=. *.proto

现在同时修改代码进行测试,填充 elliot 对象使用 SocialFollowers 类型对象:


package main

import (
    "fmt"
    "log"

    "github.com/golang/protobuf/proto"
)

func main() {

  elliot := Person{
    Name: "Elliot",
    Age:  24,
    SocialFollowers: &SocialFollowers{
        Youtube: 2500,
        Twitter: 1400,
    },
  }

  // 序列化对象
  data, err := proto.Marshal(&elliot)
  if err != nil {
    log.Fatal("marshaling error: ", err)
  }

  // 反序列化对象进行验证
  newElliot := &Person{}
  err = proto.Unmarshal(data, newElliot)
  if err != nil {
    log.Fatal("unmarshaling error: ", err)
  }

  // 输出 `newElliot` 对象属性进行验证
  fmt.Println(newElliot.GetName())
  fmt.Println(newElliot.GetAge())
  fmt.Println(newElliot.SocialFollowers.GetTwitter())
  fmt.Println(newElliot.SocialFollowers.GetYoutube())
}

运行程序输出结果:


Elliot
24
1400
2500

4. 总结

本文我们学习了Go应用中如何使用 protocol buffer 数据格式。

到此这篇关于Golang Protocol Buffer案例详解的文章就介绍到这了,更多相关Golang Protocol Buffer内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: Golang Protocol Buffer案例详解

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

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

猜你喜欢
  • Golang Protocol Buffer案例详解
    Golang Protocol Buffer教程 本文介绍如何在Go应用中利用Protocol Buffer数据格式。主要包括什么是Protocol Buffer数据格式,其超越传统...
    99+
    2024-04-02
  • Java之Buffer属性案例详解
    一、前言 熟悉NIO的人想必一定不会陌生buffer中position,limit,capacity这三个属性吧,之前在学习的时候遇到一个问题:就是当你先往缓冲区写入一部分数据,然后...
    99+
    2024-04-02
  • Golang安装和使用protocol-buffer流程介绍
    目录前言安装protoc编译工具编写proto文件生成指定语言的proto文件调用proto制作插件前言 protocol buffer是Google发布的一种独立的数据交换格式,类...
    99+
    2024-04-02
  • golang内存对齐的概念及案例详解
    什么是内存对齐 为保证程序顺利高效的运行,编译器会把各种类型的数据安排到合适的地址,并占用合适的长度,这就是内存对齐。 每种类型的对齐值就是它的对齐边界,内存对齐要求数据存储地址以及...
    99+
    2024-04-02
  • NTP(Network Time Protocol)协议详解
    一、NTP的基本概念: NTP(Network Time Protocol)------网络时间协议-----应用层协议,用来在分布式时间服务器和客户端之间进行时间同步。 二、采用NTP的目的: 是对...
    99+
    2023-09-10
    网络 服务器 运维 NTP time protocol
  • Golang在爬虫开发中的应用案例详解
    go 语言以并发性和高性能著称,使其成为网络爬虫开发的理想选择。创建网站爬虫: go 语言提供简洁易学的语法,适用于快速编写爬虫。分布式爬虫: go 语言的 goroutine 和消息队...
    99+
    2024-05-12
    go 爬虫 golang 高可扩展性
  • Java BigDecimal案例详解
    引言   float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提...
    99+
    2024-04-02
  • Android HandlerThread案例详解
    HandlerThread 顾名思义就是一种可以使用 Handler 的 Thread。日常开发中我们经常会通过创建一个 Thread 去执行任务,有多个任务就多创建几个线程实现,这...
    99+
    2024-04-02
  • Java JNDI案例详解
    JNDI的理解 JNDI是 Java 命名与文件夹接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之中的一个,不少专家觉得...
    99+
    2024-04-02
  • Java Map.entry案例详解
       Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>,Map.Entry 是Map中的一个接口,...
    99+
    2024-04-02
  • Java ResourceBundle案例详解
    JAVA中ResourceBundle使用详解 这个类主要用来解决国际化和本地化问题。国际化和本地化可不是两个概念,两者都是一起出现的。可以说,国际化的目的就是为...
    99+
    2024-04-02
  • C# TreeNode案例详解
    目录添加节点删除修改方法1:方法二:添加节点 private void Form1_Load(object sender, EventArgs e) { tree...
    99+
    2024-04-02
  • C++ namespace案例详解
    在C++语言编写的程序中,变量和函数等的作用范围是有一定限制的。比如,在函数体中定义的一个临时变量就不可以在函数体外使用。为了解决变量和函数等的作用范围,在C++语言中引入了名空间的...
    99+
    2024-04-02
  • Java WeakHashMap案例详解
    WeakHashMap 继承于AbstractMap,实现了Map接口。 和HashMap一样,WeakHashMap 也是一个散列表,它存储的内容也是键值对(key-value)映...
    99+
    2024-04-02
  • Java Assert.assertEquals案例详解
    junit.framework包下的Assert提供了多个断言方法. 主用于比较测试传递进去的两个参数. Assert.assertEquals();及其重载方法: 1. 如果两者一...
    99+
    2024-04-02
  • JavaScript offsetParent案例详解
    1. offsetParent定义:那么offsetParent就是距离该子元素最近的进行过定位的父元素(position:absolute  relative fixed...
    99+
    2024-04-02
  • Java CharacterEncodingFilter案例详解
    一、什么是CharacterEncodingFilter 官方解释如下 是spring内置过滤器的一种,用来指定请求或者响应的编码格式。在web开发中经常被从来使用 二、Chara...
    99+
    2024-04-02
  • C# Assembly.Load案例详解
     我们在使用C# 语言的Assembly.Load 来加载托管程序集并使用反射功能时,一般需要先通过Assembly.Load(), Assembly.LoadFrom()...
    99+
    2024-04-02
  • Mybatis SqlSession案例详解
    目录前言创建事务Transaction创建执行器Executor创建DefaultSqlSession对象总结前言 老规矩,先上案例代码,我们按照这个案例一步一步的搞定Mybatis...
    99+
    2023-05-16
    Mybatis SqlSession Mybatis SqlSession案例
  • NodeJS中Buffer模块详解
    一,开篇分析 所谓缓冲区Buffer,就是 "临时存贮区" 的意思,是暂时存放输入输出数据的一段内存。 JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一个与String对等的全局...
    99+
    2022-06-04
    详解 模块 NodeJS
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作