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;
不应该Thrift引发错误或是否还有其他可能正确检查是否已设置所有必填字段? 否则,我认为该关键字没有真正的意义。
答案 0 :(得分:3)
是的,如果反序列化时数据不存在,则应获得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;
}
请注意,Thrift不关心该字段是否包含有效数据。这完全取决于序列化方面。
Diwaker Gupta's "Missing Guide"解释了required
的优点和缺点。