在 Cap'n Proto 中使用唯一 ID 的示例

Examples of using unique IDs in Cap'n Proto

Cap'n Proto documentation 包含关于唯一 ID 背后基本原理的一句话:

IDs exist to provide a relatively short yet unambiguous way to refer to a type or annotation from another context.

我找不到任何此类引用的示例。有人可以指点我吗?谢谢

Cap'n Proto 自己的 RPC 协议就是一个例子。 RPC 接收器可以潜在地实现任意一组接口。因此,调用者通过发送接口的类型 ID 和方法编号来指定他们希望调用的方法。参见 Call.interfaceId in rpc.capnp.

任何查看注解的东西也往往需要使用 ID,因为编译模式中的注解仅由其 ID 标识。因此,检查注释的代码将需要通过 ID 进行检查。例如,请参阅 Cap'n Proto 自己的 C++ 代码生成器中的 this helper function and this call site,它需要遵守为文件设置 C++ 名称space 的注释。

综上所述,一般来说,您应该谨慎使用类型 ID。在协议中使用类型 ID 有点像在 C++ 中依赖 dynamic_cast —— 它并不总是坏的,但它暗示了一个糟糕的设计,它不像它可能的那样是类型安全的。例如,如果您有一条消息可能包含 N 种不同类型中的一种,您可能会想将其定义为:

# BAD DESIGN
struct MyApplicationMessage {
  typeId @0 :UInt64;
  value @1 :AnyStruct;
}

通常,您真正想要的是一个union,它完全包含此消息所需的类型集。如果您使用 union,则类型 ID 无关紧要(并且您在线上保存了 space,因为 union 标记只有 2 个字节而不是 8 个字节)。