「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
第一次写博客写的不好,望请见谅希望各位海涵,希望可以帮到大家。