You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否在Protobuf消息中添加向量字段以生成Rust结构体?

Can I add Vec<bool> and Vec<Vec<bool>> fields to Protobuf-generated Rust structs without changing the code generation workflow?

I'm working with a large production project where we use Protobuf definitions to generate both Go and Rust types. Our current Protobuf includes a message like this:

syntax = "proto3";
// ... other definitions
message myStruct {
    int32 obj_id = 1;
    string obj_code = 2;
    string obj_name = 3;
    // ... more fields
}
// ... more messages/enums

We generate Go code with protoc-gen-go and Rust code with protoc-gen-rust via scripts, and we can't refactor our type generation workflow. Now I need to add the following fields to some structs in the generated Rust code:

pub struct myClass {
    // ... existing fields like obj_id
    bool_vec: Vec<bool>,
    bool_vec_vec: Vec<Vec<bool>>,
    // ...
}

Is this achievable with Protobuf? If yes, how should I modify the Protobuf definition?

Answer

Absolutely, you can pull this off by updating your Protobuf definition appropriately—no changes to your existing code generation workflow are needed, which is perfect for your production environment constraints. Here's how to do it step by step:

1. Add the Vec<bool> equivalent field

In Protobuf, a repeated boolean field maps directly to a Vec<bool> in the generated Rust code. Just add a repeated bool field to your target message, making sure to use an unused field number (critical for maintaining backward compatibility with existing data and code):

message myClass {
    // ... keep all existing fields with their original field numbers
    int32 obj_id = 1; // example existing field
    // New field for Vec<bool>
    repeated bool bool_vec = 10; // pick any unused number starting from 1
}

When you regenerate your Rust code with your existing script, this will produce exactly the bool_vec: Vec<bool> field you need.

2. Add the Vec<Vec<bool>> equivalent field

Protobuf doesn't support direct nested repeated fields (like repeated repeated bool), but we can work around this with a tiny nested message that wraps the inner boolean vector. Then we use a repeated field of that message to get the 2D vector behavior:

message myClass {
    // ... existing fields
    int32 obj_id = 1;
    repeated bool bool_vec = 10;

    // Define a nested message to hold the inner boolean vector
    message BoolVector {
        repeated bool values = 1;
    }

    // New field for Vec<Vec<bool>>
    repeated BoolVector bool_vec_vec = 11; // another unused field number
}

When regenerated, the Rust code will look like this:

pub struct myClass {
    // ... existing fields
    pub bool_vec: ::std::vec::Vec<bool>,
    pub bool_vec_vec: ::std::vec::Vec<myClass_BoolVector>,
    // ...
}

pub struct myClass_BoolVector {
    pub values: ::std::vec::Vec<bool>,
}

To use this as a Vec<Vec<bool>>, you can easily convert it with a simple iterator (e.g., my_class.bool_vec_vec.iter().map(|v| v.values.clone()).collect()). If you need this often, consider wrapping the generated struct in a helper struct in your application code (never edit the generated file directly!).

3. Regenerate code and verify

Run your existing scripts to regenerate Go and Rust code. The changes will be fully backward-compatible because:

  • We used unused field numbers, so existing data won't be corrupted or misinterpreted
  • Protobuf handles unknown fields gracefully—older versions of your code will simply ignore these new fields if they receive data containing them

This approach fits perfectly with your requirement to keep the existing code generation workflow intact while adding the new vector fields.

内容的提问来源于stack exchange,提问作者m.raynal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:05:32