Cap'n Proto文档包含关于唯一 ID 背后基本原理的一句话:
ID 的存在是为了提供一种相对较短但明确的方式来引用另一个上下文中的类型或注释。
我找不到任何这种引用的例子。有人可以指点我吗?谢谢。
Cap'n Proto 自己的 RPC 协议就是一个例子。一个 RPC 接收器可以潜在地实现任意的接口集。因此,调用者通过发送接口的类型 ID 和方法号来指定他们希望调用的方法。见Call.interfaceId
中rpc.capnp
。
任何查看注解的东西也往往需要使用 ID,因为编译模式中的注解仅由它们的 ID 标识。因此,检查注解的代码需要通过 ID 进行检查。例如,请参阅Cap'n Proto 自己的 C++ 代码生成器中的这个帮助函数和这个调用站点,它需要遵守为文件设置 C++ 命名空间的注释。
综上所述,总的来说,您应该警惕使用类型 ID。在协议中使用类型 ID 有点像在 C++ 中依赖dynamic_cast
——它并不总是很糟糕,但它暗示了一个糟糕的设计,它没有尽可能地安全。例如,如果您的消息可能包含 N 种不同类型中的一种,您可能很想将其定义为:
# BAD DESIGN
struct MyApplicationMessage {
typeId @0 :UInt64;
value @1 :AnyStruct;
}
通常,您真正想要的是一个union
包含该消息预期类型的集合。如果您使用 a union
,则类型 ID 无关紧要(并且您可以节省线路空间,因为union
标签只有 2 个字节而不是 8 个字节)。