Go protobuf 的简单应用

news2024/11/23 9:38:13

环境搭建

安装 protobuf 编译器

https://github.com/protocolbuffers/protobuf/releases
在这里插入图片描述

解压,将bin目录加入环境变量

安装 protocol-gen-go 生成器

用于生成Go代码
https://github.com/protocolbuffers/protobuf-go/releases
在这里插入图片描述
解压,将可执行文件加入到环境变量内

或使用go install github.com/protocolbuffers/protobuf-go@latest 直接安装

使用Goland

创建项目example
并且执行 go mod init example

安装Protocol Buffers插件

在这里插入图片描述

创建user.proto文件

在这里插入图片描述

syntax = "proto3"; // 指定该文件 proto语法版本,目前有2,3

// option go_package = "path;name"; path 表示生成的go文件的存放地址,会自动生成目录
// name 表示生成的文件所属的包名
option go_package = "./service";


// 指定文件生成后的package
package service;

// 通信用的消息
message User {
  string name = 1;
  int32  aga = 2;
}

打开命令行

输入 protoc --go_out=./ ./user.proto 为user.proto生成Go代码
此时目录结构为:
在这里插入图片描述
user.pb.go文件为生成文件

// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// 	protoc-gen-go v1.28.1
// 	protoc        v3.21.12
// source: user.proto

// 指定文件生成后的package

package service

import (
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
	reflect "reflect"
	sync "sync"
)

const (
	// Verify that this generated code is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
	// Verify that runtime/protoimpl is sufficiently up-to-date.
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)

// 通信用的消息
type User struct {
	state         protoimpl.MessageState
	sizeCache     protoimpl.SizeCache
	unknownFields protoimpl.UnknownFields

	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Aga  int32  `protobuf:"varint,2,opt,name=aga,proto3" json:"aga,omitempty"`
}

func (x *User) Reset() {
	*x = User{}
	if protoimpl.UnsafeEnabled {
		mi := &file_user_proto_msgTypes[0]
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		ms.StoreMessageInfo(mi)
	}
}

func (x *User) String() string {
	return protoimpl.X.MessageStringOf(x)
}

func (*User) ProtoMessage() {}

func (x *User) ProtoReflect() protoreflect.Message {
	mi := &file_user_proto_msgTypes[0]
	if protoimpl.UnsafeEnabled && x != nil {
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
		if ms.LoadMessageInfo() == nil {
			ms.StoreMessageInfo(mi)
		}
		return ms
	}
	return mi.MessageOf(x)
}

// Deprecated: Use User.ProtoReflect.Descriptor instead.
func (*User) Descriptor() ([]byte, []int) {
	return file_user_proto_rawDescGZIP(), []int{0}
}

func (x *User) GetName() string {
	if x != nil {
		return x.Name
	}
	return ""
}

func (x *User) GetAga() int32 {
	if x != nil {
		return x.Aga
	}
	return 0
}

var File_user_proto protoreflect.FileDescriptor

var file_user_proto_rawDesc = []byte{
	0x0a, 0x0a, 0x75, 0x73, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x73, 0x65,
	0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x2c, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a,
	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
	0x65, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03,
	0x61, 0x67, 0x61, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}

var (
	file_user_proto_rawDescOnce sync.Once
	file_user_proto_rawDescData = file_user_proto_rawDesc
)

func file_user_proto_rawDescGZIP() []byte {
	file_user_proto_rawDescOnce.Do(func() {
		file_user_proto_rawDescData = protoimpl.X.CompressGZIP(file_user_proto_rawDescData)
	})
	return file_user_proto_rawDescData
}

var file_user_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
var file_user_proto_goTypes = []interface{}{
	(*User)(nil), // 0: service.User
}
var file_user_proto_depIdxs = []int32{
	0, // [0:0] is the sub-list for method output_type
	0, // [0:0] is the sub-list for method input_type
	0, // [0:0] is the sub-list for extension type_name
	0, // [0:0] is the sub-list for extension extendee
	0, // [0:0] is the sub-list for field type_name
}

func init() { file_user_proto_init() }
func file_user_proto_init() {
	if File_user_proto != nil {
		return
	}
	if !protoimpl.UnsafeEnabled {
		file_user_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
			switch v := v.(*User); i {
			case 0:
				return &v.state
			case 1:
				return &v.sizeCache
			case 2:
				return &v.unknownFields
			default:
				return nil
			}
		}
	}
	type x struct{}
	out := protoimpl.TypeBuilder{
		File: protoimpl.DescBuilder{
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
			RawDescriptor: file_user_proto_rawDesc,
			NumEnums:      0,
			NumMessages:   1,
			NumExtensions: 0,
			NumServices:   0,
		},
		GoTypes:           file_user_proto_goTypes,
		DependencyIndexes: file_user_proto_depIdxs,
		MessageInfos:      file_user_proto_msgTypes,
	}.Build()
	File_user_proto = out.File
	file_user_proto_rawDesc = nil
	file_user_proto_goTypes = nil
	file_user_proto_depIdxs = nil
}

执行go mod tidy 拉取依赖

在这里插入图片描述
user.pb.go很显然,不让我们手动编辑

序列化与反序列化

创建main.go文件

package main

import (
	"example/service"
	"fmt"
	"google.golang.org/protobuf/proto"
)

func main() {
	user := &service.User{
		Name: "张三",
		Age:  20,
	}

	// 序列化
	bys, err := proto.Marshal(user)
	if err != nil {
		panic(err)
	}

	// 反序列化

	user1 := &service.User{}
	err = proto.Unmarshal(bys, user1)
	if err != nil {
		panic(err)
	}

	fmt.Println(user1)

}

在这里插入图片描述

proto 语法介绍

详情请查看文末链接

Reference
https://developers.google.cn/protocol-buffers/docs/proto3?hl=zh-cn#simple

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/189313.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第27章 分布式缓存数据库的定义实现

1 Core.HashHelper using System.Security.Cryptography; namespace Core { /// <summary> /// 【哈希助手--类】 /// <remarks> /// 摘要&#xff1a; /// 该类通过1个指定哈希加密算法生成1个唯一性的字符串(当前安全性较强的SHA-2包括有&#xff1a;SHA-2…

九龙证券|三胎概念股拉升…港股跳水,恒生科指重挫近5%

兔年首个交易日&#xff0c;A股迎来开门红&#xff0c;沪指开盘即打破3300点&#xff0c;创业板指一度涨近3%&#xff1b;港股却大幅下挫&#xff0c;恒生科技指数一度跌超5%。 详细来看&#xff0c;A股方面&#xff0c;两市股指全线高开&#xff0c;沪指开盘即打破3300点&…

WebDAV之葫芦儿·派盘+Keepass2Android

Keepass2Android 支持WebDAV方式连接葫芦儿派盘。 推荐一款密码管理器,允许人们使用复杂的组合进行登录,而不必记住所有的组合。 Keepass2Android可以支持大多数安卓互联网浏览器, Android设备上同步软件,还支持通过WebDAV添加葫芦儿派盘。

Versal系列0-AI Engine与Systolic Array

最近在开发VCK190时&#xff0c;发现Xilinx Versal系列的AI engine&#xff08;AIE&#xff09;&#xff0c;其实和Systolic Array&#xff08;SA&#xff09;有着很相似的地方。Xilinx工程师在研发AIE时&#xff0c;应该是有所借鉴SA的。Systolic Array最早是H. T. Kung于1982…

k8s工具kubepi介绍

目录 部署安装 登录 配置 日常操作 Kubepi是一个简单高效的k8s集群图形化管理工具&#xff0c;方便日常管理K8S集群&#xff0c;高效快速的查询日志定位问题的工具。 部署安装 持久化部署 # 创建持久化目录 mkdir -p /opt/kubepi # 安装 sudo docker run --privileged …

通信原理笔记—绪论

目录 通信的基本概念&#xff1a; 通信的目的&#xff1a;要克服某种障碍&#xff0c;实现信息高效、准确地传递。 狭义的通信系统&#xff1a; 广义的通信系统&#xff1a; 数字通信系统的基本组成&#xff1a; 数字通信的特点&#xff1a; (1)抗噪声和干扰能力强&#…

【自学Docker】Docker commit命令

Docker commit命令 大纲 docker commit命令教程 docker commit 命令用于根据 Docker容器 的更改创建一个新的 Dokcer镜像。该命令后面的 CONTAINER 可以是容器Id&#xff0c;或者是容器名。 docker commit命令语法 haicoder(www.haicoder.net)# docker commit [OPTIONS] CO…

day02_java入门

今日内容 零、 复习昨日 一、程序介绍 二、Java发展及特点 三、安装环境 四、运行机制 五、第一个程序 六、Java语言规范 七、了解DOS命令 八、作业 一、程序介绍 生活中程序: 为了到达某个目的,规定一些步骤. 计算机程序:为了完成某个功能,规定一些步骤. 模拟现实世界&#…

React的基本使用(及脚手架使用)

基本使用 1 React 的安装 安装命令&#xff1a;npm i react react-dom react 包是核心&#xff0c;提供创建元素、组件等功能react-dom 包提供 DOM 相关功能等 1. 引入 react 和 react-dom 两个 js 文件 <script src"./node_modules/react/umd/react.development.…

图、邻接矩阵、广度与深度优先、生成树

最近突然被问到这个问题&#xff0c;于是复习一下&#xff0c;用最通俗的语言解释。 图 无向图&#xff1a;如下左图各个顶点之间用不带箭头的边连接的图&#xff1b;相应的右图就是有向图 邻接矩阵 可以理解为表示上述图中顶点与顶点之间是否有直接相连的边&#xff08;有则…

定时任务组件Quartz

1 定时任务组件Quartz 1.1 Quartz介绍 Quartz是Job scheduling&#xff08;作业调度&#xff09;领域的一个开源项目&#xff0c;Quartz既可以单独使用也可以跟spring框架整合使用&#xff0c;在实际开发中一般会使用后者。使用Quartz可以开发一个或者多个定时任务&#xff0c;…

计算机网络第四章 网络层数据平面

4.0 目录[TOC]4.1 概述作用&#xff1a;主机到主机之间传输TCP segment或UDP datagram将段封装成IP datagram以及解封装IP datagram【在网络边缘和路由器上都要进行】A.两大功能&#xff1a;转发路由转发&#xff1a;从不同的端口接收数据&#xff0c;再通过合适的端口发送出去…

WPS表格:函数公式

文章目录1. ROW()、ROWS(array)1&#xff09;ROW()2&#xff09;ROWS(array)2. COUNT(参数)、COUNTA(参数)、COUNTIF(参数)1&#xff09;COUNT()2&#xff09;COUNTA()3&#xff09;COUNTIF()3. VLOOKUP(参数)、LOOKUP(参数)1&#xff09;VLOOKUP(参数)2&#xff09;LOOKUP(向量…

数据分析有发展前景吗?,零基础能学得会吗?

数据分析这门专业是近几年因大数据的出现而产生的新兴职业&#xff0c;分为大数据分析和数据分析师&#xff0c;区别在于大数据分析师要求更高&#xff0c;不仅需要数据分析的基本能力&#xff0c;还要具备编程能力、机器学习技能&#xff0c;以及本身所接触到处理的都是海量数…

webpack打包构建工具的使用和相关的配置

目录 一、 webpack的基础使用步骤 二、webpack的配置 1、入口和出口 2、 webpack打包后自动生成html文件并自动引入打包后的js 3、加载器loader 3.1、处理css文件 3.2、处理less文件 3.3、处理图片文件 3.4、处理字体文字 3.5、处理高版本js语法&#xff08;降级&#xff…

Linux locate命令

Linux locate命令用于查找符合条件的文档&#xff0c;他会去保存文档和目录名称的数据库内&#xff0c;查找合乎范本样式条件的文档或目录。一般情况我们只需要输入 locate your_file_name 即可查找指定文件。语法locate [-d ][--help][--version][范本样式...]参数&#xff1a…

Notepad++ 代码格式化插件工具

因为notepad的NppAStyle插件只支持格式化C、C、C#、Java这四种编程语言的代码&#xff0c;所以推荐使用这个CoolFormat的插件&#xff0c;相比于NPPAStyle&#xff0c;CoolFormat支持C\C\C#\CSS\HTML\Java\JavaScript\JSON\Objective-C\PHP\SQL\XML代码格式化工具。还可以作为V…

后端java模拟前端RSA.js加密登录爬虫

项目开发过程中&#xff0c;经常会遇到数据爬取需求&#xff0c;但是对于某些网站&#xff0c;由于前端加密&#xff0c;导致数据爬取不容易。比如某网站&#xff0c;前端使用RSA.js加密&#xff0c;并且后端返回对应的公钥的指数和模数&#xff0c;通过后端返回的指数和模数对…

电商如何打开数字化的破局之路

电商网购已经成为我们的日常生活&#xff0c;在如此高节奏的工作下&#xff0c;打开手机或者电脑从网上挑选自己需要的物品&#xff0c;方便快捷&#xff0c;伴随着移动互联网和月的高速发展&#xff0c;电子商务作为现今的产业在我国快速增长和兴起。 如今的电商模式多种多样&…

Elasticsearch7.8.0版本入门——JavaAPI操作(批量操作文档)

目录一、pom文件依赖二、批量操作文档 代码示例2.1、批量创建文档 代码示例2.2、批量删除文档 代码示例一、pom文件依赖 引入相关依赖 <!-- elasticsearch 依赖 --> <dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch…