Apache Fory™ 使用
本章节提供 Apache Fory™ 的快速入门示例。
原生序列化
当你只在单一语言内使用时,请始终选择原生模式。 原生模式不需要为跨语言兼容写入额外类型元信息,因此性能最好。
xlang 模式会引入额外的元信息编码开销,并且只允许序列化所有受支持语言都能映射的类型。语言特有类型在 xlang 模式下会被拒绝。
Java 序列化
如果不需要跨语言支持,请使用 Java 模式以获得最佳性能。
下面的示例展示了最基本的 Java 原生用法:创建可复用的 Java 模式运行时、注册用户类型,然后完成一次序列化和反序列化往返。实际项目中不要为每个对象重新创建 Fory 实例,而应长期复用同一个实例。
import org.apache.fory.*;
import org.apache.fory.config.*;
public class Example {
public static class Person {
String name;
int age;
}
public static void main(String[] args) {
// 创建一次 Fory 实例并重复复用。
BaseFory fory = Fory.builder()
.withLanguage(Language.JAVA)
.requireClassRegistration(true)
// 如果需要线程安全用法,请将 `build` 替换为 `buildThreadSafeFory`。
.build();
fory.register(Person.class);
Person person = new Person();
person.name = "chaokunyang";
person.age = 28;
byte[] bytes = fory.serialize(person);
Person result = (Person) fory.deserialize(bytes);
System.out.println(result.name + " " + result.age);
}
}
关于兼容模式、压缩和更多高级特性,请参见 Java 序列化指南。
Python 序列化
Python 原生模式可以作为 pickle 和 cloudpickle 的高性能替代方案。
这个示例使用 dataclass 和显式整数类型注解,让 Fory 能以更清晰的 Schema 进行高效序列化。与其他语言一样,推荐只创建一次 Fory 实例、只注册一次类型,然后在后续调用中重复使用。
from dataclasses import dataclass
import pyfory
@dataclass
class Person:
name: str
age: pyfory.int32
fory = pyfory.Fory()
fory.register_type(Person)
person = Person(name="chaokunyang", age=28)
data = fory.serialize(person)
result = fory.deserialize(data)
print(result.name, result.age)
关于类型注解、兼容模式和更多高级特性,请参见 Python 指南。
Go 序列化
Go 原生模式默认启用。注册一次结构体后,重复复用同一个 Fory 实例即可。
Go 运行时天然适配导出的 struct 字段和显式类型注册。下面的代码演示了最常见的流 程:创建 Fory、注册结构体类型、序列化一个值,再反序列化到目标结构体中。
package main
import (
"fmt"
"github.com/apache/fory/go/fory"
)
type Person struct {
Name string
Age int32
}
func main() {
f := fory.New()
if err := f.RegisterStruct(Person{}, 1); err != nil {
panic(err)
}
person := &Person{Name: "chaokunyang", Age: 28}
data, err := f.Serialize(person)
if err != nil {
panic(err)
}
var result Person
if err := f.Deserialize(data, &result); err != nil {
panic(err)
}
fmt.Printf("%s %d\n", result.Name, result.Age)
}
关于配置、struct tag 和 Schema 演进,请参见 Go 指南。
C# 序列化
C# 原生序列化使用 Apache.Fory 运行时和 [ForyObject] 模型类型。
在 C# 中,常见模式是先用 [ForyObject] 标记模型,再创建一次运行时并在使用前注册类型。示例展示的是强类型的 Serialize / Deserialize<T> API,这也是 .NET 应用中最直接的用法。
using Apache.Fory;
[ForyObject]
public sealed class Person
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
}
Fory fory = Fory.Builder().Build();
fory.Register<Person>(1);
Person person = new() { Name = "chaokunyang", Age = 28 };
byte[] data = fory.Serialize(person);
Person result = fory.Deserialize<Person>(data);
Console.WriteLine($"{result.Name} {result.Age}");
关于源代码生成器、引用跟踪和 Schema 演进,请参见 C# 指南。
Swift 序列化
Swift 原生序列化直接使用 @ForyObject 模型和 Fory 运行时。
Swift 通过宏定义模型 类型,因此示例先使用 @ForyObject 标记类型,再注册类型 ID 并完成一次强类型往返。这是 Swift 应用侧最推荐的入门方式。
import Fory
@ForyObject
struct Person: Equatable {
var name: String = ""
var age: Int32 = 0
}
let fory = Fory()
fory.register(Person.self, id: 1)
let person = Person(name: "chaokunyang", age: 28)
let data = try fory.serialize(person)
let result: Person = try fory.deserialize(data)
print("\(result.name) \(result.age)")
关于多态、Schema 演进和常见问题排查,请参见 Swift 指南。
Rust 序列化
Rust 原生模式使用 Fory::default() 和 derive 宏来实现编译期类型安全的序列化。常见模式是先为类型派生 ForyObject,注册一次类型,再重复复用已经配置好的运行时。
use fory::{Error, Fory, ForyObject};
#[derive(ForyObject, Debug, PartialEq)]
struct Person {
name: String,
age: i32,
}
fn main() -> Result<(), Error> {
let mut fory = Fory::default();
fory.register::<Person>(1)?;
let person = Person {
name: "chaokunyang".to_string(),
age: 28,
};
let bytes = fory.serialize(&person)?;
let result: Person = fory.deserialize(&bytes)?;
assert_eq!(person, result);
Ok(())
}
关于引用、多态和 row format 支持,请参见 Rust 指南。
C++ 序列化
C++ 原生模式使用 FORY_STRUCT 宏描述可序列化字段,再通过配置好的 Fory 运行时对值进行编码和解码。对于单语言 C++ 场景,建议显式设置 xlang(false),让运行时保持在原生模式。
#include "fory/serialization/fory.h"
using namespace fory::serialization;
struct Person {
std::string name;
int32_t age;
bool operator==(const Person &other) const {
return name == other.name && age == other.age;
}
FORY_STRUCT(Person, name, age);
};
int main() {
auto fory = Fory::builder().xlang(false).build();
fory.register_struct<Person>(1);
Person person{"chaokunyang", 28};
auto bytes = fory.serialize(person);
auto result = fory.deserialize<Person>(bytes.value());
assert(result.ok());
assert(person == result.value());
return 0;
}
关于 FORY_STRUCT、线程安全和 Schema 演进,请参见 C++ 指南。