一.protobuf详解
想要知道protobuf中的oneof的使用,就需要先了解protbuf及其使用,详见:[golang 微服务] 3. ProtoBuf认识,安装以及golang 中ProtoBuf使用
二.oneof关键字的使用
1.oneof介绍
在 Protocol Buffers(protobuf)中,
oneof
是一种用于表示多种可能字段中的一个字段的机制。使用oneof
可以减少消息的大小,并提高数据的可读性,因为它保证在某一时刻只有一个字段被设置
2.oneof
的基本用法
(1).案例1
在
.proto
文件中,可以这样定义一个oneof
:
syntax = "proto3";message MyMessage {oneof my_oneof {string name = 1;int32 age = 2;bool is_active = 3;}
}
在这个例子中,
MyMessage
中包含了一个oneof
字段my_oneof
,该字段可以是name
、age
或is_active
中的一个,但不能同时包含多个
(2).案例2
一个真实的proto案例: 定义isGroup字段,根据isGroup的值是true/false,list展示不同的结果
//获取统计日报数据列表响应
message ListReportDailyRes {//状态码uint64 errCode = 1;string errDesc = 2;// @gotags: json:"data"ListReportDailyResBody data = 3; // 返回分组数据统计数据
}// 返回分组数据
message ListReportDailyResBody {//当前页面数uint64 page = 1;//页大小uint64 size = 2;// @gotags: json:"totalCount"uint64 totalCount = 3; //总条数// @gotags: json:"isGroup"bool isGroup =4; // 下面的list中的数据是不是组数据, 当isGroup为true时,list下面的id表示组id(也就是group_id), 点击"详情"时,访问的是daily/detailGroup接口// 根据isGroup的值展示数据// @gotags: json:"list"oneof list {// @gotags: json:"groupList"GroupDataModelBody groupList = 5; // 分组列表: 当isGroup为true时展示组数据// @gotags: json:"memberList"GroupDetailDataModelBody memberList = 6; // 分组成员: 当isGroup为false时展示成员自己的数据}
}//分组数据model Body
message GroupDataModelBody{// @gotags: json:"totalData"TotalDataModel totalData = 1; // 总数据统计// @gotags: json:"list"repeated GroupDataModel list= 2; // 分组列表
}message GroupDetailDataModelBody{// @gotags: json:"list"repeated GroupDetailDataModel list = 1;
}//分组成员(组,成员)详细代理数据model
message GroupDetailDataModel{// @gotags: json:"id"uint64 id = 1; // 组id(group_id)/成员id(manager_id)// @gotags: json:"name"string name = 2; // 名称// @gotags: json:"new_agent_num"uint64 new_agent_num = 3; // 新增代理人数// @gotags: json:"effect_agent_num"uint64 effect_agent_num = 4; // 有效新增代理人数: exp > 0的人数// @gotags: json:"exp"uint64 exp = 5; // 代理充值金额// @gotags: json:"is_group"bool is_group = 6; // 当is_group为false时,id表示成员id(也就是manager_id),点击"详情"时,访问的是daily/detailAccount接口; 当is_group为true时,id表示组id(也就是group_id), 点击"详情"时,访问的是daily/detailGroup接口
}
3.使用 oneof
的特点
- 互斥性:在任何时候,
oneof
中只能有一个字段被设置。如果你设置了其中一个字段,其他字段会被清空 - 默认值:在未设置任何字段时,
oneof
会有一个默认值(通常是 nil 或零值) - 代码生成:使用
oneof
生成的代码会包含一些额外的方法来处理oneof
的逻辑
4.总结
在 Go 中使用 Protobuf 的
oneof
特性非常直接,你可以方便地定义互斥字段,并通过类型断言来访问这些字段。这对于在需要节省空间或需要明确字段状态的场景非常有用