go: 在proto中使用oneof类型
在proto中,可以使用OneOf类型,使用一个字段存储不同类型的数据。类似go中的interface。
假设有proto如下,Val是一个OneOf数据类型,它可以为double/int/str...中的任意一种。
TestPB中引用了value,类型为Val。
syntax = "proto3";
package protooneof;
option go_package = "pb/message";
message Val{
oneof oneof_val {
double double = 1;
int64 int = 2;
string str = 3;
bytes bytes = 4;
uint64 uint = 5;
float float = 6;
}
}
message TestPB {
Val value = 1;
}
赋值
编译这个proto,可以使用以下的代码对Val类型赋值:
msg := &message.TestPB{
Value: &message.Val{
OneofVal: &message.Val_Str{Str: "hello"}, // 对oneof赋值需要使用Val包装,然后内部指定具体的类型
},
}
同理,使用=赋值也是可以的:
msg.Value = &message.Val{
OneofVal: &message.Val_Float{Float: 123},
}
取值
假设知道值的类型,可以直接调用GetXXX方法取值。
fv := msg.GetValue().GetStr()
fmt.Printf("fv:%v\n", fv) // 输出 hello
但是如果这个值未设置或者不存在,则会返回这个类型的0值。
这就带来问题,如何判定这个值是否已设置,如果已设置是什么类型?
可以使用switch类型判定的方式来解决需求,因为已经穷举了Val所有可能的类型,如果未设置值,会打印未设置值。
switch v := msg.GetValue().GetOneofVal().(type) {
case *message.Val_Int:
fmt.Printf("int val:%v\n", v.Int)
case *message.Val_Float:
fmt.Printf("float val:%v\n", v.Float)
case *message.Val_Double:
fmt.Printf("double val:%v\n", v.Double)
case *message.Val_Str:
fmt.Printf("str val:%v\n", v.Str)
case *message.Val_Bytes:
fmt.Printf("bytes val:%v\n", v.Bytes)
case *message.Val_Uint:
fmt.Printf("uint val:%v\n", v.Uint)
default:
fmt.Printf("未设置值\n")
}
通过善用Oneof类型,可以让pb的结构更紧凑,满足更多元化的需求。
go: 在proto中使用oneof类型的更多相关文章
- Entity Framework 教程——Entity Framework中的实体类型
Entity Framework中的实体类型 : 在之前的章节中我们介绍过从已有的数据库中创建EDM,它包含数据库中每个表所对应的实体.在EF 5.0/6.0中,存在POCO 实体和动态代理实体两种. ...
- Python中内置数据类型list,tuple,dict,set的区别和用法
Python中内置数据类型list,tuple,dict,set的区别和用法 Python语言简洁明了,可以用较少的代码实现同样的功能.这其中Python的四个内置数据类型功不可没,他们即是list, ...
- 向mysql中插入Date类型的数据
先看数据库表的定义 date字段为sql.date类型.我要向其中插入指定的日期和当前日期. 一.插入当前日期 思路:先获取当前系统,在将当前系统时间转换成sql类型的时间,然后插入数据库.代码如下 ...
- 在文件夹中 的指定类型文件中 查找字符串(CodeBlocks+GCC编译,控制台程序,仅能在Windows上运行)
说明: 程序使用 io.h 中的 _findfirst 和 _findnext 函数遍历文件夹,故而程序只能在 Windows 下使用. 程序遍历当前文件夹,对其中的文件夹执行递归遍历.同时检查遍历到 ...
- Python 中的枚举类型~转
Python 中的枚举类型 摘要: 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期.月份.状态等. 枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表 ...
- UNIX中的文件类型
Unix的文件类型信息包含在stat结构的st_mode成员中可以用宏确定文件类型: 普通文件(S_ISREG()):包含某种形式数据的常用文件类型 目录文件(S_ISDIR()):这种文件包含其他文 ...
- 命名空间“System.Web”中不存在类型或命名空间名称“Optimization”(是否缺少程序集引用?)
今天,在.net4.5,mvc4下新建了个区域,运行起来就报这个错误: 命名空间"System.Web"中不存在类型或命名空间名称"Optimization"( ...
- C#解决一个奇怪的,命名空间“XXX”中不存在类型或命名空间名称“xxx”的问题
最近做项目时,引用了一个第三方的程序集,代码层面没有任何语法错误,编译提示:命名空间"System.Net"中不存在类型或命名空间名称"FtpClient".是 ...
- [delphi]向ImageList中加入png类型的资源图片
向ImageList中动态加入Png图片有些失真,经过多方查询,发现需要将Bitmap的AlphaFormat指定一下. //向ImageList中加入png类型的资源图片 procedure Add ...
- 在 Typescript 2.0 中使用 @types 类型定义
在 Typescript 2.0 中使用 @type 类型定义 基于 Typescript 开发的时候,很麻烦的一个问题就是类型定义.导致在编译的时候,经常会看到一连串的找不到类型的提示.解决的方式经 ...
随机推荐
- 个人常用的 matplotlib 绘图模板
import numpy as np import matplotlib import matplotlib.pyplot as plt matplotlib.rcParams['mathtext.f ...
- 关于“内网穿透”的一些知识(续3)—— NAT类型判断
前文: 关于"内网穿透"的一些知识(续2)-- 端口预测 ------------------------------------------- 本文是对前面几篇文章的补充.这里要 ...
- Java实现微信登录(网页授权)
1.背景 实际开发中,使用第三方登录是非常常见的业务... 这样可以大提高用户体验,没必要一来就要注册,或者登录之类的... 并且开发一个登录或者注册严格来说也是非常麻烦的(各种防止攻击.机器操作等) ...
- Analysis of Set Union Algorithms 题解
题意简述 有一个集合,初始为空,你需要写一个数据结构,支持: 0 x 表示将 \(x\) 加入该集合,其中 \(x\) 为一由 \(\texttt{0} \sim \texttt{9}\) 组成的数字 ...
- [CEOI2007] 树的匹配 Treasury 题解
前言 题目链接:洛谷. 题目简述 给一棵树,问你这棵树的最大匹配是多少,并且计算出有多少种最大匹配. 题目分析 先来考虑较简单的最大匹配数.对于某一个结点,它有以下三种状态: 不参与匹配: 和某一个儿 ...
- 数字名片工具 BBlog:使用一个链接,快速创建和分享你的信息主页和数字花园
数字名片 BBlog:使用一个链接,快速创建和分享你的信息主页和数字花园 随着移动互联网技术的快速发展,数字名片产品已成为现代社交和网络营销的重要工具.数字名片可以帮助个人和企业在各种场合中展示和分享 ...
- 09-canvas绘制坐标系
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...
- Camera | 3.瑞芯微平台MIPI摄像头常用调试命令
瑞芯微专栏 前面2篇我们讲解了camera的一些基础概念和知识. 本文主要讲述在瑞芯微平台上摄像头开发常用的调试命令. 0.环境 soc : rk3568 board: EVB1-DDR4-V10 软 ...
- 使用 prefetchComponents 进行组件预取
title: 使用 prefetchComponents 进行组件预取 date: 2024/8/17 updated: 2024/8/17 author: cmdragon excerpt: 摘要: ...
- ubuntu 16.04 安装Python3.8虚拟环境
virtualenv为应用提供了隔离的Python运行环境,可以解决不同应用间多版本的冲突问题. virtualenv会把用户指定版本的python复制到虚拟环境下,并修改相关的环境变量,使得pyth ...