Protobuf(Protocol Buffers)是一种跨平台、跨语言的结构化数据存储格式,被广泛用于网络通信和数据存储等领域。Protobuf通过.proto文件进行数据描述,这些文件可以用于生成各平台的数据访问类。
在实际开发中,我们经常会遇到不再使用或者需要替换的字段,为了保持向后兼容性,我们需要知道如何弃用这些字段,而不是暴力地直接删除该字段(一开始我不清楚的情况下都是直接暴力删除的-_-|)。
在 Proto 文件中,我们可以使用不同的方法来标记和处理弃用字段。以以下message为例
syntax = "proto3";
package my_package;
message MyMessage {
int32 normal_field = 1;
...
// deprecated_field is we want to deprecate.
string deprecated_field = 20;
}
deprecated 选项是一种简单而直观的方式,用于标记一个字段为弃用。当其他开发人员尝试使用这个字段时,编译器或代码生成工具会发出警告,提醒他们不再建议使用该字段。
syntax = "proto3";
package my_package;
message MyMessage {
int32 normal_field = 1;
...
// deprecated_field is we want to deprecate.
string deprecated_field = 20 [deprecated = true];
}
注意,我们依旧可以使用deprecated_field 这个字段,并没有被真正删除,只是编译器会发出警告,警告我们不要使用该字段了。
reserved 关键字允许我们将字段标记为“保留”,使用 reserved 可以更加明确地表明字段的弃用情况,同时也提供了更多的灵活性,以便将来重新使用这些字段。
syntax = "proto3";
package my_package;
message MyMessage {
int32 normal_field = 1;
...
// deprecated_field is we want to deprecate.
reserved 20; // Deprecated field: deprecated_field
}
但是,单纯reserved掉字段id,可能会导致一些编译问题,我们一般会同时reserved掉字段名:
syntax = "proto3";
package my_package;
message MyMessage {
int32 normal_field = 1;
...
// deprecated_field is we want to deprecate.
reserved 20; // Deprecated field: deprecated_field
reserved "deprecated_field ";
}
在工作中,我比较推荐的做法是最后一种,同时reserved 字段id和字段名。
推荐使用reserved 关键字来标记字段ID和字段名,因为它提供了更严格和清晰的方式来处理弃用字段:
明确性:使用 reserved 关键字能够清晰地表明我们的意图,即这些字段被保留以作为已弃用字段。其他开发人员在看到这样的标记时会更容易理解。
防止误用:如果只使用 deprecated 选项,其他开发人员可能会意外地继续使用已弃用字段,因为编译器通常只生成警告,而不会阻止字段的使用。而使用 reserved 可以防止字段被错误使用,因为编译器会报错,不允许引用被保留的字段。
可扩展性:reserved 关键字允许我们灵活地重新分配字段ID或者重新使用已弃用字段。对于未来的协议版本升级非常有用,因为它保留了我们对已弃用字段的控制。