「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

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

全部评论

相关推荐

01-17 12:35
吉首大学 Java
秋招之BrianGriffin:自己的工作自己做!😡
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务