「Golang」关于通过proto消息名,创建proto.Message对象

  前几天在做一些proto相关业务逻辑编写,在编写过程中,需要通过proto的message full name 去动态的创建一个proto.Message对象,在网上找一些相关的内容也没找到,所以就自己研究了一下并且实现了这个功能。

下面是proto v1版本实现代码。

//该实现仅用于proto v1版本实现 即	github.com/golang/protobuf 库
func parseRequest(msgName protoreflect.FullName, data []byte) (proto.Message,error) {
	// 获取full name对应的message ,如果不存在则返回error
	msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
	if err != nil {
		return nil, err
	}
	//上面返回的是一个message 反射类型,需要把它new出一个 protoreflect.Message类型然后转换成protoiface.MessageV1
	//此时 根据源代码显示 proto.Message实现为 type Message = protoiface.MessageV1
	//即type Message 为 protoiface.MessageV1 的别名
	msg := proto.MessageV1(msgType.New())
	err = proto.Unmarshal(data, msg)
	if err != nil {
		return nil, err
	}
	return msg, nil
}

proto v2版本实现如下

//该实现仅用于proto v2版本实现 即"google.golang.org/protobuf/proto"库
func parseRequest(msgName protoreflect.FullName, data []byte) (proto.Message,error) {
	// 获取full name对应的message ,如果不存在则返回error
	msgType, err := protoregistry.GlobalTypes.FindMessageByName(msgName)
	if err != nil {
		return nil, err
	}
	//上面返回的是一个message type 反射类型,需要把它new出一个 protoreflect.Message类型然后转换成protoreflect.ProtoMessage
	//此时 根据源代码显示 proto.Message实现为 type Message = protoreflect.ProtoMessage	
	//即type Message 为 protoreflect.ProtoMessage的别名
	msg := msgType.New().Interface()
	err = proto.Unmarshal(data, msg)
	if err != nil {
		return nil, err
	}
	return msg, nil
}

  整体业务流程是,传进一个proto的 full name 然后根据这个名字去创建对应的message,然后把data 解析到这个message中。

关于protov1 v2版本的区别,v2版本的动态特性更强。具体区别请看下面的链接
https://www.infoq.cn/article/dyX9bq5uFyK4hCEPgmuj

第一次写博客写的不好,望请见谅希望各位海涵,希望可以帮到大家。

我已开通自己的公众号【Echo的技术笔记】
日后的文章发布会主要在公众号上发布
希望各位关注一下
谢谢大家啦
在这里插入图片描述

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
在 Go 中使用 Protocol Buffers(简称 proto)可以通过以下步骤进行: 1. 安装 protoc 编译器:Protocol Buffers 使用 protoc 编译器将 .proto 文件编译成 Go 代码。你可以从 [Protocol Buffers GitHub 仓库](https://github.com/protocolbuffers/protobuf/releases) 下载适合你操作系统的 protoc 编译器,并将其添加到系统 PATH 环境变量中。 2. 编写 .proto 文件:创建一个为 example.proto 的文本文件,并使用 Protocol Buffers 的语法定义消息结构和服务。 示例 example.proto 文件: ```protobuf syntax = "proto3"; package example; message Person { string name = 1; int32 age = 2; repeated string hobbies = 3; } service Greeting { rpc SayHello (Person) returns (Person); } ``` 3. 生成 Go 代码:使用 protoc 编译器将 .proto 文件生成 Go 代码。在终端中运行以下命令: ```shell protoc --go_out=. example.proto ``` 这将在当前目录下生成一个 example.pb.go 文件,其中包含了根据 .proto 文件生成的 Go 结构体和服务代码。 4. 在 Go 代码中使用生成的代码:在你的 Go 代码中导入生成的代码文件,并使用其中定义的结构体和服务进行编程。 示例 Go 代码: ```go package main import ( "fmt" "log" example "path/to/generated/code" // 导入生成的代码包 "google.golang.org/protobuf/proto" ) func main() { person := &example.Person{ Name: "John", Age: 25, Hobbies: []string{"reading", "coding"}, } data, err := proto.Marshal(person) if err != nil { log.Fatal(err) } // 在这里可以将 data 发送给其他地方进行传输或存储 newPerson := &example.Person{} err = proto.Unmarshal(data, newPerson) if err != nil { log.Fatal(err) } fmt.Println(newPerson.GetName()) // 输出:John } ``` 以上就是使用 Protocol Buffers 在 Go 中的基本步骤。你可以根据自己的需求定义更复杂的消息结构和服务,并使用生成的 Go 代码进行序列化、反序列化等操作。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值