【问题标题】:How to instantiate a generic Cap'n Proto type in pycapnp如何在 pycapnp 中实例化通用 Cap'n Proto 类型
【发布时间】:2019-08-01 06:54:04
【问题描述】:

我不知道如何在 pycapnp 中实例化 Option(T) 类型。

我尝试实例化一条新消息,然后设置 'some' 的值,但这样做会丢失类型信息。

struct Option(T) {
  union {
    none @0 :Void;
    some @1 :T;
  }
}

struct Something {
  a @0 :Int16;
}
o = Option.new_message()
o.some = Something.new_message(a=5)
o.some.a // throws error

我希望该选项通过添加的结构成为类型,但它会丢失所有类型信息,并且我无法访问放置在“某些”联合值中的对象的成员。

【问题讨论】:

    标签: python generics capnproto


    【解决方案1】:

    Cap'n Proto 泛型并非真正设计为以这种方式工作。它们是为静态类型检查而设计的(考虑到静态类型的语言,即不是 Python)。泛型类型的实例不能在事后“被类型化”——该类型必须在构造时静态/已知。

    如果未指定类型参数,则假定为AnyPointer。我相信这意味着您需要像这样访问some

    o.some.as_struct(Something).a
    

    我认为在 Python 中没有办法构造一个在运行时指定类型参数的泛型类型。真正使用泛型的唯一方法是包含类型指定类型参数,例如:

    struct ContainingType {
      option @0 :Option(Something);
    }
    

    如果您随后构造一个ContainingType,然后访问它的option 字段,您将获得一个Option 对象,该对象知道some 的类型是Something,而不是AnyPointer

    【讨论】:

      【解决方案2】:

      我想提供一个例子来说明我是如何工作的:

      struct Request(PayloadType) {
        type @0 :Text;
        payload @1: PayloadType;
      }
      
      struct PingPayload {
        num @0 :Int64;
      }
      

      创建有效负载

      payload = self.capnp_models['ping_payload'].PingPayload.new_message()
      payload.num = 999
      
      req = self.capnp_models['request'].Request.new_message()
      req.type = 'ping'
      req.payload = payload
      

      读取有效负载

      request = self.capnp_models['request'].Request.from_bytes(req)
      payload = request.payload.as_struct(self.capnp_models['ping_payload'].PingPayload)
      print(str(payload.num)) # Prints 999
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-13
        • 2017-06-02
        • 1970-01-01
        • 1970-01-01
        • 2021-12-06
        相关资源
        最近更新 更多