我有一个描述可能每月,每年或特定日期发生的事件的原型。其基本结构是:
enum PeriodType {
MONTHLY = 1;
YEARLY = 2;
SPECIFIC_DATE = 3;
}
message Event {
PeriodType period_type = 1;
...
}
但应该有一种方法来指定发生的日期。所以我做了以下原型:
message Event {
PeriodType period_type = 1;
Date period_specific_date = 2;
...
}
在我们的内部代码审核期间,该解决方案被禁止。原因是“proto不应包含仅在另一个字段中存在特定值时使用的字段”。我需要以某种方式重写它,以便event
period_type == MONTHLY
时event.getPeriodSpecificDate()
不能调用message Event {
message Period {
PeriodType period_type = 1;
}
message PeriodWithDate {
Period period = 1;
Date period_specific_date = 2;
}
oneof period {
Period period_without_date = 1;
PeriodWithDate period_with_date = 2;
}
...
}
。我怎么能这样做?
一个可能的解决方案是这样做:
p
但这并没有真正解决问题,看起来像一个可怕的矫枉过正。还有其他办法吗?
答案 0 :(得分:2)
如果给出了日期,则实际上并不需要PeriodType。 所以你可以这样做:
enum RegularPeriod
{
MONTHLY = 1;
YEARLY = 2;
}
oneof period
{
RegularPeriod regular = 1;
Date specific_date = 2;
}
答案 1 :(得分:1)
在我们的内部代码审核期间,该解决方案被禁止。原因是“proto不应包含仅在另一个字段中存在特定值时才使用的字段”。
告诉您的评论者我是Protocol Buffers v2的作者,我认为这条规则是不切实际的。虽然在类型系统中强制执行所有内容很有诱惑力,但实际上Protobuf类型系统的表现力远不足以制定这种硬性规则。在实际使用中,实际上很常见的是具有记录约束的字段,例如“如果字段X具有值Y,则该字段应该仅存在”,并且这确实没问题。
据说,在这种特殊情况下,@ jpa的答案是合理的。它有权衡:你现在在你的代码中有多个级别的分支,这可能很难看,如果你的协议变得更复杂,可能会变得更加丑陋。但它确实设法在类型系统中表达所有约束。
(不接受我的回答,接受@ jpa的。)