节俭必需的场C

Thrift Required Field C++

本文关键字:      更新时间:2023-10-16
Thrift File:
struct Sub {
1: required i32 number
}
struct Message {
1: required Sub sub
}
Message m;
m.write(protocol.get());
Message parsedM;
parsedM.read(protocol2.get());
std::cout << parsedM.sub.number;

Sourcecode

不应该延长提出错误,或者是否有其他可能正确检查是否设置了所有必需字段?否则,我在该关键字中看不到真正的意义。

简短答案

是的,如果在避免时不存在数据,则应获得TProtocolException::INVALID_DATA。在您的示例中不是这种情况,因此您不会得到例外。

长答案

这是基于您的IDL生成的C read()方法之一。提防isset_number及其使用方式:

uint32_t Sub::read(::apache::thrift::protocol::TProtocol* iprot) {
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;
  xfer += iprot->readStructBegin(fname);
  using ::apache::thrift::protocol::TProtocolException;
  bool isset_number = false;
  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          xfer += iprot->readI32(this->number);
          isset_number = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }
  xfer += iprot->readStructEnd();
  if (!isset_number)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

那么为什么在您的示例中起作用?

正如我们已经看到的,required字段预计将存在于应序列化数据中,而optional(和默认)字段可能丢失。但是标记为required(和默认字段)的字段也总是写入到传输的字段,仅当分配值时,optional。因此,您阅读了之前序列化的数据:

uint32_t Sub::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  xfer += oprot->writeStructBegin("Sub");
  xfer += oprot->writeFieldBegin("number", ::apache::thrift::protocol::T_I32, 1);
  xfer += oprot->writeI32(this->number);
  xfer += oprot->writeFieldEnd();
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

请注意,节俭不在乎该字段是否包含有效数据。这都是关于序列化方面的。

建议阅读

Diwaker Gupta的"缺失指南"解释了required的优点。

相关文章:
  • 没有找到相关文章