【问题标题】:Use any previous message in a new message在新消息中使用任何以前的消息
【发布时间】:2019-12-21 02:23:33
【问题描述】:

我有一个 protobuf 文件,我在其中定义了多个消息,这些消息都继承了相同的特征(在消息定义中使用 option (scalapb.message).extends = "Event";)。

我想创建一个名为 MultiEvent 的新消息,其中可能包含从 Event 继承的任何消息的序列。

事件在 Scala 代码中被定义为简单的trait Event

这个想法是能够一次发送包含多条消息的特殊消息。

syntax = "proto3";

import "scalapb/scalapb.proto";

package com.some.package;

message A {
  option (scalapb.message).extends = "Event";
  string name = 1;
}

message B {
  option (scalapb.message).extends = "Event";
  string field = 1;
}

message C {
  option (scalapb.message).extends = "Event";
  string otherField = 1;
}

message MultiEvent {
  option (scalapb.message).extends = "Event";
  repeated Event seq = 1; // this line is problematic
}

我收到错误消息:"Event" is not defined.。 理想情况下,从代码中,该字段将是一个简单的 Seq,它重复提供,但它仅适用于标量类型。 我在网上发现 Any 可能能够完成我想要的,但是在尝试使用它时出现错误。

解决此类问题的常用方法是什么?枚举?转化?

谢谢。

【问题讨论】:

  • 我也有类似的问题。

标签: scala protocol-buffers scalapb


【解决方案1】:

通常的方式是oneof(在Protocol Buffers 3中)。 repeated oneof 是非法的:

Repeated oneof was in the initial proposal but as we later found out, there were lots many complicated corner cases in wire and API. We decided not to add repeated for oneof.

您始终可以定义一个包含 oneof 的消息,并改为使用该消息的重复字段。

所以

message Event {
  oneof sealed_value {
    A a = 1;
    B b = 2;
    C c = 3;
    ...
  }
}

然后是repeated Event,就像你现在拥有的那样。

使用 sealed_value 作为名称启用 ScalaPB 的 sealed oneof 支持。

【讨论】:

  • 我明白你的意思,但在代码中,我需要检查保存值的 a、b 和 c。看起来它增加了一层间接性......也许没有更好的方法了,面团。 :-/
  • @Darko - 为密封的 oneofs 生成的代码不会添加额外的间接性(必须使用名称 sealed_value)。你最终会得到我认为你会喜欢的 API。如果生成的代码中有一些对您不起作用的东西,您能否更清楚地了解它是什么?不知道您所说的“我需要检查 a、b 和 c 的值”是什么意思。见scalapb.github.io/sealed-oneofs.html
  • 你说得对,一开始我是在检查生成的代码,得到了这样的想法。
猜你喜欢
  • 2023-03-17
  • 2015-10-19
  • 2019-01-14
  • 2020-02-18
  • 2022-11-26
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多