我最近将 gRPC
与 proto3
一起使用,并且我注意到 required
和 Optional
已已在新语法中删除。
有人能解释一下为什么在 proto3 中删除了必需/可选吗?这种约束似乎是使定义稳健所必需的。
语法原型(prototype)2:
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
语法原型(prototype)3:
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
最佳答案
required
的实用性一直是许多争论和激烈争论的核心。双方都有大型营地。一个阵营喜欢保证某个值的存在,并且愿意接受其局限性,但另一个阵营则认为 require
是危险的或无用的,因为它无法安全地添加或删除。
让我详细解释一下为什么应谨慎使用 required
字段。如果您已经在使用原型(prototype),则无法添加必填字段,因为旧应用程序不会提供该字段,并且应用程序通常不能很好地处理故障。您可以确保首先升级所有旧应用程序,但是很容易犯错误,并且如果您将原型(prototype)存储在任何数据存储中(甚至是短暂的,例如内存缓存)。删除必填字段时也适用同样的情况。
许多必填字段“显然”是必填的,直到......它们不是。假设您有一个用于 Get
方法的 id
字段。这显然是必需的。不过,稍后您可能需要将 id
从 int 更改为 string,或将 int32 更改为 int64。这需要添加一个新的 muchBetterId
字段,现在您只剩下必须指定的旧 id
字段,但最终会被完全忽略。
当这两个问题结合在一起时,有益的必填
字段的数量就变得有限,并且各阵营争论它是否仍然有值(value)。 required
的反对者并不一定反对这个想法,而是反对它目前的形式。一些人建议开发一个更具表现力的验证库,可以检查required
以及name.length > 10
等更高级的内容,同时确保拥有更好的故障模型。
Proto3 总体上似乎更倾向于简单性,并且 required
删除更简单。但也许更有说服力的是,当与其他功能结合使用时,删除 required
对于 proto3 来说是有意义的,例如删除原语的字段存在和删除覆盖默认值。
我不是 protobuf 开发人员,在这个问题上也不具有权威性,但我仍然希望这个解释是有用的。
关于protocol-buffers - 为什么 Protocol Buffers 3 中删除了必需和可选,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31801257/