protobuf repeated详解

一、repeated的定义以及使用

protobuf中repeated是一种用来表示一个字段可以被重复多次的数据类型,它类似于C++中的vector和Java中的List,可以用来存储一组值。

syntax = "proto3";

message Person {
    string name = 1;
    int32 age = 2;
    repeated string address = 3;
}

在上述代码中,我们定义了一个Person消息对象,其中address是一个repeated类型的属性,表示可以有多个地址。

使用repeated的好处在于它可以在一个字段中存储多个数据,这样可以减少定义属性的个数,提高数据的可效率性。

二、repeated的序列化和反序列化

序列化和反序列化是protobuf最重要的功能之一,可以将消息对象转化为二进制格式,便于网络传输和存储。repeated的序列化和反序列化操作与标量类型基本相同,可以借助protobuf库中的函数实现。

例如,我们需要对上述定义的Person消息对象进行序列化和反序列化操作,可以参考下面的代码:

#include 
#include 
#include "person.pb.h" //protobuf生成的头文件

using namespace std;

int main() {
    //创建一个Person对象,并设置属性值
    tutorial::Person person;
    person.set_name("张三");
    person.set_age(20);
    person.add_address("北京市");
    person.add_address("上海市");

    //将Person对象序列化为二进制数据
    string buffer;
    person.SerializeToString(&buffer);

    //将二进制数据反序列化为Person对象
    tutorial::Person newPerson;
    newPerson.ParseFromString(buffer);

    //输出newPerson对象的属性值
    cout << "姓名:" << newPerson.name() << endl;
    cout << "年龄:" << newPerson.age() << endl;
    cout << "地址:";
    for (int i = 0; i < newPerson.address_size(); i++) {
        cout << newPerson.address(i) << " ";
    }
    cout << endl;
    return 0;
}

可以看到,在上述代码中,我们首先创建了一个Person对象,并设置了属性值,然后通过SerializeToString函数将其序列化为二进制数据。反序列化时,则需要先创建一个空的Person对象,通过ParseFromString函数将二进制数据反序列化为新的对象。

三、repeated的默认值

repeated字段的默认值是一个空列表,该列表包含0个元素。当我们需要添加元素时,可以通过调用add_XXX函数向列表中添加元素。

下面是一个示例代码:

syntax = "proto3";

message Person {
    string name = 1;
    int32 age = 2;
    repeated string address = 3 [default = "北京市"];
}

在上述代码中,我们通过在address字段后加上default选项,指定了address字段的默认值为“北京市”。这意味着,在创建Person消息对象时,如果没有为address属性赋值,那么该属性会默认为“北京市”。当然,我们也可以在创建对象后,通过调用add_address函数向address列表中添加元素。

四、repeated字段的遍历

遍历repeated字段的方式与遍历C++中的vector类似,可以使用for循环来迭代列表中的每一个元素。下面是一个示例代码:

#include 
#include "person.pb.h"

using namespace std;

int main() {
    //创建一个Person对象,并向address字段中添加三个元素
    tutorial::Person person;
    person.add_address("北京市");
    person.add_address("上海市");
    person.add_address("广州市");

    //遍历address字段,并输出每一个元素的值
    for (int i = 0; i < person.address_size(); i++) {
        cout << person.address(i) << endl;
    }
    return 0;
}

五、repeated字段和map的比较

在进行开发时,我们有时需要在消息对象中存储一些键值对数据,这时可以考虑使用map数据类型。与repeated不同,map类型可以直接通过键值访问元素,而无需使用循环遍历。下面是一个示例代码:

syntax = "proto3";

message Person {
    string name = 1;
    int32 age = 2;
    map address = 3;
}

在上述代码中,我们使用了map类型来存储地址信息。代码中的map使用了string类型作为键和值的类型。对于map类型的序列化和反序列化操作,与repeated的操作类似,都可以借助protobuf库中提供的函数实现。

但是需要注意的是,由于map类型是一种关联式数据结构,其底层实现依赖于红黑树等算法,因此其性能相对于repeated略低。所以,在实际开发中,我们需要根据具体的需求选择合适的数据类型。

原创文章,作者:MTALN,如若转载,请注明出处:https://www.506064.com/n/331638.html

相关推荐

  • Python官网中文版:解决你的编程问题

    Python是一种高级编程语言,它可以用于Web开发、科学计算、人工智能等领域。Python官网中文版提供了全面的资源和教程,可以帮助你入门学习和进一步提高编程技能。 一、Pyth…

    编程 2025-04-29
  • Python计算阳历日期对应周几

    本文介绍如何通过Python计算任意阳历日期对应周几。 一、获取日期 获取日期可以通过Python内置的模块datetime实现,示例代码如下: from datetime imp…

    编程 2025-04-29
  • 银行资金管理系统总结

    银行资金管理系统是银行日常业务运营的核心支撑系统,主要负责处理银行的资金流动、结算、清算等业务。本文将从功能特点、技术架构、安全性以及未来发展趋势等多个方面对银行资金管理系统进行详…

    编程 2025-04-29
  • 如何查看Anaconda中Python路径

    对Anaconda中Python路径即conda环境的查看进行详细的阐述。 一、使用命令行查看 1、在Windows系统中,可以使用命令提示符(cmd)或者Anaconda Pro…

    编程 2025-04-29
  • 如何修改mysql的端口号

    本文将介绍如何修改mysql的端口号,方便开发者根据实际需求配置对应端口号。 一、为什么需要修改mysql端口号 默认情况下,mysql使用的端口号是3306。在某些情况下,我们需…

    编程 2025-04-29
  • 英语年龄用连字符号(Hyphenation for English Age)

    英语年龄通常使用连字符号表示,比如 “five-year-old boy”。本文将从多个方面探讨英语年龄的连字符使用问题。 一、英语年龄的表达方式 英语中表…

    编程 2025-04-29
  • Idea新建文件夹没有java class的解决方法

    如果你在Idea中新建了一个文件夹,却没有Java Class,应该如何解决呢?下面从多个方面来进行解答。 一、检查Idea设置 首先,我们应该检查Idea的设置是否正确。打开Id…

    编程 2025-04-29
  • 金额选择性序列化

    本文将从多个方面对金额选择性序列化进行详细阐述,包括其定义、使用场景、实现方法等。 一、定义 金额选择性序列化指根据传入的金额值,选择是否进行序列化,以达到减少数据传输的目的。在实…

    编程 2025-04-29
  • Python中引入上一级目录中函数

    Python中经常需要调用其他文件夹中的模块或函数,其中一个常见的操作是引入上一级目录中的函数。在此,我们将从多个角度详细解释如何在Python中引入上一级目录的函数。 一、加入环…

    编程 2025-04-29
  • Python列表中负数的个数

    Python列表是一个有序的集合,可以存储多个不同类型的元素。而负数是指小于0的整数。在Python列表中,我们想要找到负数的个数,可以通过以下几个方面进行实现。 一、使用循环遍历…

    编程 2025-04-29