字段配置
本页说明如何在 C++ 中配置序列化字段级元信息。
概述
Apache Fory™ 在编译期提供两种字段元信息配置方式:
fory::field<>模板:在 struct 定义中内联声明元信息FORY_FIELD_TAGS宏:在 struct 外部附加元信息(非侵入)
这些机制可用于:
- Tag ID:为 schema 演进分配紧凑数值 ID
- 可空控制:将指针字段标记为可空
- 引用跟踪:为共享指针启用引用跟踪
fory::field 模板
template <typename T, int16_t Id, typename... Options>
class field;
模板参数
| 参数 | 说明 |
|---|---|
T | 底层字段类型 |
Id | 字段 tag ID(int16_t),用于紧凑序列化 |
Options | 可选标签:fory::nullable、fory::ref 等 |
基本用法
#include "fory/serialization/fory.h"
using namespace fory::serialization;
struct Person {
fory::field<std::string, 0> name;
fory::field<int32_t, 1> age;
fory::field<std::optional<std::string>, 2> nickname;
};
FORY_STRUCT(Person, name, age, nickname);
fory::field<> 是透明包装,可像底层类型一样使用:
Person person;
person.name = "Alice"; // Direct assignment
person.age = 30;
std::string n = person.name; // Implicit conversion
int a = person.age.get(); // Explicit get()
标签类型
fory::nullable:可空字段
将智能指针字段标记为可空(可为 nullptr):
struct Node {
fory::field<std::string, 0> name;
fory::field<std::shared_ptr<Node>, 1, fory::nullable> next; // Can be nullptr
};
FORY_STRUCT(Node, name, next);
适用类型: std::shared_ptr<T>、std::unique_ptr<T>
说明: 对原生值类型或字符串的可空语义,请使用 std::optional<T>:
// Correct: use std::optional for nullable primitives
fory::field<std::optional<int32_t>, 0> optional_value;
// Wrong: nullable is not allowed for primitives
// fory::field<int32_t, 0, fory::nullable> value; // Compile error!
fory::not_null
显式声明指针字段不可空。虽然这是智能指针的默认行为,但可用于增强可读性:
fory::field<std::shared_ptr<Data>, 0, fory::not_null> data; // Must not be nullptr
适用类型: std::shared_ptr<T>、std::unique_ptr<T>
fory::ref
为共享指针字段启用引用跟踪。多个字段引用同一对象时,仅序列化一次并保持共享关系:
struct Graph {
fory::field<std::string, 0> name;
fory::field<std::shared_ptr<Graph>, 1, fory::ref> left; // Ref tracked
fory::field<std::shared_ptr<Graph>, 2, fory::ref> right; // Ref tracked
};
FORY_STRUCT(Graph, name, left, right);
适用类型: 仅 std::shared_ptr<T>(需要共享所有权)
组合标签
共享指针可组合多个标签:
// Nullable + ref tracking
fory::field<std::shared_ptr<Node>, 0, fory::nullable, fory::ref> link;